下面列出了com.google.protobuf.MessageLite#Builder ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private static <ProtoBuilderT extends MessageLite.Builder>
FieldValueSetter<ProtoBuilderT, Object> getProtoFieldValueSetter(
Field field, Multimap<String, Method> methods, Class<ProtoBuilderT> builderClass) {
if (field.getType().isLogicalType(OneOfType.IDENTIFIER)) {
OneOfType oneOfType = field.getType().getLogicalType(OneOfType.class);
TreeMap<Integer, FieldValueSetter<ProtoBuilderT, Object>> oneOfSetters = Maps.newTreeMap();
for (Field oneOfField : oneOfType.getOneOfSchema().getFields()) {
FieldValueSetter setter = getProtoFieldValueSetter(oneOfField, methods, builderClass);
oneOfSetters.put(getFieldNumber(oneOfField), setter);
}
return createOneOfSetter(field.getName(), oneOfSetters, builderClass);
} else {
Method method = getProtoSetter(methods, field.getName(), field.getType());
return JavaBeanUtils.createSetter(
FieldValueTypeInformation.forSetter(method, protoSetterPrefix(field.getType())),
new ProtoTypeConversionsFactory());
}
}
public void testMessageLiteToBuilderAndMergeFrom() throws Exception {
TypicalData input = TypicalData.newBuilder().setMyInt(123).build();
MessageLite msg = TypicalData.getDefaultInstance();
// mergeFrom(byte[], ExtensionRegistryLite)
MessageLite.Builder builder = msg.toBuilder();
builder.mergeFrom(input.toByteString().toByteArray(), ExtensionRegistry.getEmptyRegistry());
assertEquals(123, ((TypicalData) builder.build()).getMyInt());
// mergeFrom(byte[])
builder = msg.toBuilder();
builder.mergeFrom(input.toByteString().toByteArray());
assertEquals(123, ((TypicalData) builder.build()).getMyInt());
// mergeFrom(ByteString, ExtensionRegistryLite)
builder = msg.toBuilder();
builder.mergeFrom(input.toByteString(), ExtensionRegistry.getEmptyRegistry());
assertEquals(123, ((TypicalData) builder.build()).getMyInt());
// mergeFrom(ByteString)
builder = msg.toBuilder();
builder.mergeFrom(input.toByteString());
assertEquals(123, ((TypicalData) builder.build()).getMyInt());
}
@Override
public MessageLite deserialize(MessageLite w) throws IOException {
MessageLite.Builder builder;
if (w == null) {
builder = newBuilder();
} else {
builder = w.newBuilderForType();
}
if (builder.mergeDelimitedFrom(in)) {
return builder.build();
}
return null;
}
@Override
protected void encode(ChannelHandlerContext ctx, MessageLiteOrBuilder msg, List<Object> out)
throws Exception {
if (msg instanceof MessageLite) {
out.add(wrappedBuffer(((MessageLite) msg).toByteArray()));
return;
}
if (msg instanceof MessageLite.Builder) {
out.add(wrappedBuffer(((MessageLite.Builder) msg).build().toByteArray()));
}
}
@Override
public void encode(SocketChannel socketChannel, Object obj) throws Exception {
byte[] bytes = null;
if (obj instanceof MessageLite) {
bytes = ((MessageLite) obj).toByteArray();
}
if (obj instanceof MessageLite.Builder) {
bytes = ((MessageLite.Builder) obj).build().toByteArray();
}
super.encode(socketChannel, bytes);
}
static Method getProtoSetter(Multimap<String, Method> methods, String name, FieldType fieldType) {
final TypeDescriptor<MessageLite.Builder> builderDescriptor =
TypeDescriptor.of(MessageLite.Builder.class);
return methods.get(protoSetterName(name, fieldType)).stream()
// Setter methods take only a single parameter.
.filter(m -> m.getParameterCount() == 1)
// For nested types, we don't use the version that takes a builder.
.filter(
m -> !TypeDescriptor.of(m.getGenericParameterTypes()[0]).isSubtypeOf(builderDescriptor))
.findAny()
.orElseThrow(IllegalArgumentException::new);
}
@Experimental(Kind.SCHEMAS)
@Nullable
public static <ProtoBuilderT extends MessageLite.Builder> SchemaUserTypeCreator getBuilderCreator(
Class<?> protoClass, Schema schema, FieldValueTypeSupplier fieldValueTypeSupplier) {
Class<ProtoBuilderT> builderClass = getProtoGeneratedBuilder(protoClass);
if (builderClass == null) {
return null;
}
Multimap<String, Method> methods = ReflectUtils.getMethodsMap(builderClass);
List<FieldValueSetter<ProtoBuilderT, Object>> setters =
schema.getFields().stream()
.map(f -> getProtoFieldValueSetter(f, methods, builderClass))
.collect(Collectors.toList());
return createBuilderCreator(protoClass, builderClass, setters, schema);
}
@Experimental(Kind.SCHEMAS)
static <ProtoBuilderT extends MessageLite.Builder> SchemaUserTypeCreator createBuilderCreator(
Class<?> protoClass,
Class<?> builderClass,
List<FieldValueSetter<ProtoBuilderT, Object>> setters,
Schema schema) {
try {
DynamicType.Builder<Supplier> builder =
BYTE_BUDDY
.with(new InjectPackageStrategy(builderClass))
.subclass(Supplier.class)
.method(ElementMatchers.named("get"))
.intercept(new BuilderSupplier(protoClass));
Supplier supplier =
builder
.visit(
new AsmVisitorWrapper.ForDeclaredMethods()
.writerFlags(ClassWriter.COMPUTE_FRAMES))
.make()
.load(ReflectHelpers.findClassLoader(), ClassLoadingStrategy.Default.INJECTION)
.getLoaded()
.getDeclaredConstructor()
.newInstance();
return new ProtoCreatorFactory<>(supplier, setters);
} catch (InstantiationException
| IllegalAccessException
| NoSuchMethodException
| InvocationTargetException e) {
throw new RuntimeException(
"Unable to generate a creator for class " + builderClass + " with schema " + schema);
}
}
@Override
protected void encode(
ChannelHandlerContext ctx, MessageLiteOrBuilder msg, List<Object> out) throws Exception {
if (msg instanceof MessageLite) {
out.add(wrappedBuffer(((MessageLite) msg).toByteArray()));
return;
}
if (msg instanceof MessageLite.Builder) {
out.add(wrappedBuffer(((MessageLite.Builder) msg).build().toByteArray()));
}
}
public void testMessageLite() throws Exception {
// Mainly a compilation test for the Lite classes.
MessageLite.Builder builder = TypicalData.newBuilder();
MessageLite message = builder.build();
assertTrue(message instanceof MessageLite);
message.toByteString();
}
public void testMessageLiteInterface() throws Exception {
ExtensionRegistryLite registry = ExtensionRegistryLite.newInstance();
TypicalData data = TypicalData.newBuilder().build();
MessageLite messageLite = data;
MessageLite.Builder builderLite = messageLite.newBuilderForType();
messageLite.writeTo(new ByteArrayOutputStream());
messageLite.writeDelimitedTo(new ByteArrayOutputStream());
builderLite.mergeFrom(new ByteArrayInputStream(new byte[0]));
builderLite.mergeFrom(new ByteArrayInputStream(new byte[0]), registry);
builderLite.mergeDelimitedFrom(new ByteArrayInputStream(new byte[0]));
builderLite.mergeDelimitedFrom(new ByteArrayInputStream(new byte[0]), registry);
assertEquals(0, messageLite.getSerializedSize());
}
@Override
public MessageLite deserialize(DeserializationContext unusedContext, CodedInputStream codedIn)
throws IOException, SerializationException {
// Don't hold on to full byte array when constructing this proto.
codedIn.enableAliasing(false);
try {
MessageLite.Builder builder = builderSupplier.get();
codedIn.readMessage(builder, ExtensionRegistryLite.getEmptyRegistry());
return builder.build();
} catch (InvalidProtocolBufferException e) {
throw new SerializationException("Failed to parse proto of type " + type, e);
} finally {
codedIn.enableAliasing(true);
}
}
/**
* Given a message-or-builder, returns a message, invoking the builder if necessary.
*/
@SuppressWarnings("unchecked")
public static <I extends MessageLiteOrBuilder, O extends MessageLite> O built(@Nullable I msg) {
return msg instanceof MessageLite.Builder
? (O) ((MessageLite.Builder) msg).build()
: (O) msg;
}
/**
* Given a message-or-builder, return a builder, invoking toBuilder() if necessary.
*/
@SuppressWarnings("unchecked")
public static <I extends MessageLiteOrBuilder, O extends MessageLite.Builder> O builder(
@Nullable I msg) {
return msg instanceof MessageLite
? (O) ((MessageLite) msg).toBuilder()
: (O) msg;
}
/**
* Updates every builder from a sequence.
*
* @param objs List of builders to update
* @param updater Update function. The {@code apply()} method can decide or not to update each
* object, and it's expected to return {@code true} if some update was made
* @return {@code true} if at least one object was updated
*/
public static <B extends MessageLite.Builder> boolean update(
Iterable<B> objs, Function<B, Boolean> updater) {
checkNotNull(updater);
boolean updated = false;
for (B obj : objs) {
updated |= updater.apply(obj);
}
return updated;
}
static <ProtoBuilderT extends MessageLite.Builder>
FieldValueSetter<ProtoBuilderT, Object> createOneOfSetter(
String name,
TreeMap<Integer, FieldValueSetter<ProtoBuilderT, Object>> setterMethodMap,
Class protoBuilderClass) {
Set<Integer> indices = setterMethodMap.keySet();
boolean contiguous = isContiguous(indices);
int[] keys = setterMethodMap.keySet().stream().mapToInt(Integer::intValue).toArray();
DynamicType.Builder<FieldValueSetter> builder =
ByteBuddyUtils.subclassSetterInterface(
BYTE_BUDDY, protoBuilderClass, OneOfType.Value.class);
builder =
builder
.method(ElementMatchers.named("name"))
.intercept(FixedValue.reference(name))
.method(ElementMatchers.named("set"))
.intercept(new OneOfSetterInstruction(contiguous, keys));
builder =
builder
// Store a field with the list of individual setters. The get() instruction will pick
// the appropriate
// getter from the list based on the case value of the OneOf.
.defineField(
CASE_SETTERS_FIELD_NAME,
FieldValueSetter[].class,
Visibility.PRIVATE,
FieldManifestation.FINAL)
.defineConstructor(Modifier.PUBLIC)
.withParameters(List.class)
.intercept(new OneOfSetterConstructor());
List<FieldValueSetter> setters = Lists.newArrayList(setterMethodMap.values());
try {
return builder
.visit(new AsmVisitorWrapper.ForDeclaredMethods().writerFlags(ClassWriter.COMPUTE_FRAMES))
.make()
.load(ReflectHelpers.findClassLoader(), ClassLoadingStrategy.Default.INJECTION)
.getLoaded()
.getDeclaredConstructor(List.class)
.newInstance(setters);
} catch (InstantiationException
| IllegalAccessException
| NoSuchMethodException
| InvocationTargetException e) {
throw new RuntimeException("Unable to generate a setter for setter '" + name + "'", e);
}
}
/**
* Receive a protocol buffer message over the connection and parse it into
* the given builder. Note that this method will block until the message is
* received fully or some error occurs.
*/
void receiveProtoMessage(MessageLite.Builder messageBuilder)
throws IOException;
/**
* Constructor.
*
* @param builderSupplier reference to a proto's newBuilder method
*/
public MessageLiteCodec(Supplier<MessageLite.Builder> builderSupplier) {
this.builderSupplier = builderSupplier;
this.type = builderSupplier.get().buildPartial().getClass();
}