private static void eagerlyMergeMessageSetExtension(
        CodedInputStream input,
        ExtensionRegistry.ExtensionInfo extension,
        ExtensionRegistryLite extensionRegistry,
        Message.Builder builder,
        FieldSet<FieldDescriptor> extensions)
        throws IOException {

      FieldDescriptor field = extension.descriptor;
      Message value = null;
      if (hasOriginalMessage(builder, extensions, field)) {
        Message originalMessage = getOriginalMessage(builder, extensions, field);
        Message.Builder subBuilder = originalMessage.toBuilder();
        input.readMessage(subBuilder, extensionRegistry);
        value = subBuilder.buildPartial();
      } else {
        value = input.readMessage(extension.defaultInstance.getParserForType(), extensionRegistry);
      }

      if (builder != null) {
        builder.setField(field, value);
      } else {
        extensions.setField(field, value);
      }
    }
 /** helper method to handle {@code builder} and {@code extensions}. */
 private static Message getOriginalMessage(
     Message.Builder builder, FieldSet<FieldDescriptor> extensions, FieldDescriptor field) {
   if (builder != null) {
     return (Message) builder.getField(field);
   } else {
     return (Message) extensions.getField(field);
   }
 }
 /** helper method to handle {@code builder} and {@code extensions}. */
 private static boolean hasOriginalMessage(
     Message.Builder builder, FieldSet<FieldDescriptor> extensions, FieldDescriptor field) {
   if (builder != null) {
     return builder.hasField(field);
   } else {
     return extensions.hasField(field);
   }
 }
    private static void mergeMessageSetExtensionFromBytes(
        ByteString rawBytes,
        ExtensionRegistry.ExtensionInfo extension,
        ExtensionRegistryLite extensionRegistry,
        Message.Builder builder,
        FieldSet<FieldDescriptor> extensions)
        throws IOException {

      FieldDescriptor field = extension.descriptor;
      boolean hasOriginalValue = hasOriginalMessage(builder, extensions, field);

      if (hasOriginalValue || ExtensionRegistryLite.isEagerlyParseMessageSets()) {
        // If the field already exists, we just parse the field.
        Message value = null;
        if (hasOriginalValue) {
          Message originalMessage = getOriginalMessage(builder, extensions, field);
          Message.Builder subBuilder = originalMessage.toBuilder();
          subBuilder.mergeFrom(rawBytes, extensionRegistry);
          value = subBuilder.buildPartial();
        } else {
          value =
              extension
                  .defaultInstance
                  .getParserForType()
                  .parsePartialFrom(rawBytes, extensionRegistry);
        }
        setField(builder, extensions, field, value);
      } else {
        // Use LazyField to load MessageSet lazily.
        LazyField lazyField = new LazyField(extension.defaultInstance, extensionRegistry, rawBytes);
        if (builder != null) {
          // TODO(xiangl): it looks like this method can only be invoked by
          // ExtendableBuilder, but I'm not sure. So I double check the type of
          // builder here. It may be useless and need more investigation.
          if (builder instanceof ExtendableBuilder) {
            builder.setField(field, lazyField);
          } else {
            builder.setField(field, lazyField.getValue());
          }
        } else {
          extensions.setField(field, lazyField);
        }
      }
    }
 /** helper method to handle {@code builder} and {@code extensions}. */
 private static void mergeOriginalMessage(
     Message.Builder builder,
     FieldSet<FieldDescriptor> extensions,
     FieldDescriptor field,
     Message.Builder subBuilder) {
   Message originalMessage = getOriginalMessage(builder, extensions, field);
   if (originalMessage != null) {
     subBuilder.mergeFrom(originalMessage);
   }
 }
 /** helper method to handle {@code builder} and {@code extensions}. */
 private static void setField(
     Message.Builder builder,
     FieldSet<FieldDescriptor> extensions,
     FieldDescriptor field,
     Object value) {
   if (builder != null) {
     builder.setField(field, value);
   } else {
     extensions.setField(field, value);
   }
 }
Пример #7
0
  public void testParsingUninitialized() throws Exception {
    TestRequiredForeign.Builder builder = TestRequiredForeign.newBuilder();
    builder.getOptionalMessageBuilder().setDummy2(10);
    ByteString bytes = builder.buildPartial().toByteString();
    Message.Builder abstractMessageBuilder =
        new AbstractMessageWrapper.Builder(TestRequiredForeign.newBuilder());
    // mergeFrom() should not throw initialization error.
    abstractMessageBuilder.mergeFrom(bytes).buildPartial();
    try {
      abstractMessageBuilder.mergeFrom(bytes).build();
      fail();
    } catch (UninitializedMessageException ex) {
      // pass
    }

    // test DynamicMessage directly.
    Message.Builder dynamicMessageBuilder =
        DynamicMessage.newBuilder(TestRequiredForeign.getDescriptor());
    // mergeFrom() should not throw initialization error.
    dynamicMessageBuilder.mergeFrom(bytes).buildPartial();
    try {
      dynamicMessageBuilder.mergeFrom(bytes).build();
      fail();
    } catch (UninitializedMessageException ex) {
      // pass
    }
  }
Пример #8
0
 @Override
 public boolean hasField(Descriptors.FieldDescriptor field) {
   return wrappedBuilder.hasField(field);
 }
Пример #9
0
 @Override
 public Object getField(Descriptors.FieldDescriptor field) {
   return wrappedBuilder.getField(field);
 }
Пример #10
0
    /**
     * Like {@link #mergeFrom(CodedInputStream, UnknownFieldSet.Builder, ExtensionRegistryLite,
     * Message.Builder)}, but parses a single field. Package-private because it is used by
     * GeneratedMessage.ExtendableMessage.
     *
     * @param tag The tag, which should have already been read.
     * @return {@code true} unless the tag is an end-group tag.
     */
    @SuppressWarnings("unchecked")
    static boolean mergeFieldFrom(
        final CodedInputStream input,
        final UnknownFieldSet.Builder unknownFields,
        final ExtensionRegistryLite extensionRegistry,
        final Message.Builder builder,
        final int tag)
        throws IOException {
      final Descriptor type = builder.getDescriptorForType();

      if (type.getOptions().getMessageSetWireFormat() && tag == WireFormat.MESSAGE_SET_ITEM_TAG) {
        mergeMessageSetExtensionFromCodedStream(input, unknownFields, extensionRegistry, builder);
        return true;
      }

      final int wireType = WireFormat.getTagWireType(tag);
      final int fieldNumber = WireFormat.getTagFieldNumber(tag);

      final FieldDescriptor field;
      Message defaultInstance = null;

      if (type.isExtensionNumber(fieldNumber)) {
        // extensionRegistry may be either ExtensionRegistry or
        // ExtensionRegistryLite.  Since the type we are parsing is a full
        // message, only a full ExtensionRegistry could possibly contain
        // extensions of it.  Otherwise we will treat the registry as if it
        // were empty.
        if (extensionRegistry instanceof ExtensionRegistry) {
          final ExtensionRegistry.ExtensionInfo extension =
              ((ExtensionRegistry) extensionRegistry).findExtensionByNumber(type, fieldNumber);
          if (extension == null) {
            field = null;
          } else {
            field = extension.descriptor;
            defaultInstance = extension.defaultInstance;
          }
        } else {
          field = null;
        }
      } else {
        field = type.findFieldByNumber(fieldNumber);
      }

      if (field == null
          || wireType
              != FieldSet.getWireFormatForFieldType(
                  field.getLiteType(), field.getOptions().getPacked())) {
        // Unknown field or wrong wire type.  Skip.
        return unknownFields.mergeFieldFrom(tag, input);
      }

      if (field.getOptions().getPacked()) {
        final int length = input.readRawVarint32();
        final int limit = input.pushLimit(length);
        if (field.getLiteType() == WireFormat.FieldType.ENUM) {
          while (input.getBytesUntilLimit() > 0) {
            final int rawValue = input.readEnum();
            final Object value = field.getEnumType().findValueByNumber(rawValue);
            if (value == null) {
              // If the number isn't recognized as a valid value for this
              // enum, drop it (don't even add it to unknownFields).
              return true;
            }
            builder.addRepeatedField(field, value);
          }
        } else {
          while (input.getBytesUntilLimit() > 0) {
            final Object value = FieldSet.readPrimitiveField(input, field.getLiteType());
            builder.addRepeatedField(field, value);
          }
        }
        input.popLimit(limit);
      } else {
        final Object value;
        switch (field.getType()) {
          case GROUP:
            {
              final Message.Builder subBuilder;
              if (defaultInstance != null) {
                subBuilder = defaultInstance.newBuilderForType();
              } else {
                subBuilder = builder.newBuilderForField(field);
              }
              if (!field.isRepeated()) {
                subBuilder.mergeFrom((Message) builder.getField(field));
              }
              input.readGroup(field.getNumber(), subBuilder, extensionRegistry);
              value = subBuilder.build();
              break;
            }
          case MESSAGE:
            {
              final Message.Builder subBuilder;
              if (defaultInstance != null) {
                subBuilder = defaultInstance.newBuilderForType();
              } else {
                subBuilder = builder.newBuilderForField(field);
              }
              if (!field.isRepeated()) {
                subBuilder.mergeFrom((Message) builder.getField(field));
              }
              input.readMessage(subBuilder, extensionRegistry);
              value = subBuilder.build();
              break;
            }
          case ENUM:
            final int rawValue = input.readEnum();
            value = field.getEnumType().findValueByNumber(rawValue);
            // If the number isn't recognized as a valid value for this enum,
            // drop it.
            if (value == null) {
              unknownFields.mergeVarintField(fieldNumber, rawValue);
              return true;
            }
            break;
          default:
            value = FieldSet.readPrimitiveField(input, field.getLiteType());
            break;
        }

        if (field.isRepeated()) {
          builder.addRepeatedField(field, value);
        } else {
          builder.setField(field, value);
        }
      }

      return true;
    }
Пример #11
0
 @Override
 public Builder newBuilderForField(Descriptors.FieldDescriptor field) {
   return new Builder(wrappedBuilder.newBuilderForField(field));
 }
Пример #12
0
 @Override
 public UnknownFieldSet getUnknownFields() {
   return wrappedBuilder.getUnknownFields();
 }
Пример #13
0
 @Override
 public Message.Builder getFieldBuilder(FieldDescriptor field) {
   return wrappedBuilder.getFieldBuilder(field);
 }
Пример #14
0
 @Override
 public Builder setRepeatedField(Descriptors.FieldDescriptor field, int index, Object value) {
   wrappedBuilder.setRepeatedField(field, index, value);
   return this;
 }
Пример #15
0
 @Override
 public int getRepeatedFieldCount(Descriptors.FieldDescriptor field) {
   return wrappedBuilder.getRepeatedFieldCount(field);
 }
Пример #16
0
 @Override
 public Builder setField(Descriptors.FieldDescriptor field, Object value) {
   wrappedBuilder.setField(field, value);
   return this;
 }
Пример #17
0
    /** Called by {@code #mergeFieldFrom()} to parse a MessageSet extension. */
    private static void mergeMessageSetExtensionFromCodedStream(
        final CodedInputStream input,
        final UnknownFieldSet.Builder unknownFields,
        final ExtensionRegistryLite extensionRegistry,
        final Message.Builder builder)
        throws IOException {
      final Descriptor type = builder.getDescriptorForType();

      // The wire format for MessageSet is:
      //   message MessageSet {
      //     repeated group Item = 1 {
      //       required int32 typeId = 2;
      //       required bytes message = 3;
      //     }
      //   }
      // "typeId" is the extension's field number.  The extension can only be
      // a message type, where "message" contains the encoded bytes of that
      // message.
      //
      // In practice, we will probably never see a MessageSet item in which
      // the message appears before the type ID, or where either field does not
      // appear exactly once.  However, in theory such cases are valid, so we
      // should be prepared to accept them.

      int typeId = 0;
      ByteString rawBytes = null; // If we encounter "message" before "typeId"
      Message.Builder subBuilder = null;
      FieldDescriptor field = null;

      while (true) {
        final int tag = input.readTag();
        if (tag == 0) {
          break;
        }

        if (tag == WireFormat.MESSAGE_SET_TYPE_ID_TAG) {
          typeId = input.readUInt32();
          // Zero is not a valid type ID.
          if (typeId != 0) {
            final ExtensionRegistry.ExtensionInfo extension;

            // extensionRegistry may be either ExtensionRegistry or
            // ExtensionRegistryLite.  Since the type we are parsing is a full
            // message, only a full ExtensionRegistry could possibly contain
            // extensions of it.  Otherwise we will treat the registry as if it
            // were empty.
            if (extensionRegistry instanceof ExtensionRegistry) {
              extension =
                  ((ExtensionRegistry) extensionRegistry).findExtensionByNumber(type, typeId);
            } else {
              extension = null;
            }

            if (extension != null) {
              field = extension.descriptor;
              subBuilder = extension.defaultInstance.newBuilderForType();
              final Message originalMessage = (Message) builder.getField(field);
              if (originalMessage != null) {
                subBuilder.mergeFrom(originalMessage);
              }
              if (rawBytes != null) {
                // We already encountered the message.  Parse it now.
                subBuilder.mergeFrom(CodedInputStream.newInstance(rawBytes.newInput()));
                rawBytes = null;
              }
            } else {
              // Unknown extension number.  If we already saw data, put it
              // in rawBytes.
              if (rawBytes != null) {
                unknownFields.mergeField(
                    typeId,
                    UnknownFieldSet.Field.newBuilder().addLengthDelimited(rawBytes).build());
                rawBytes = null;
              }
            }
          }
        } else if (tag == WireFormat.MESSAGE_SET_MESSAGE_TAG) {
          if (typeId == 0) {
            // We haven't seen a type ID yet, so we have to store the raw bytes
            // for now.
            rawBytes = input.readBytes();
          } else if (subBuilder == null) {
            // We don't know how to parse this.  Ignore it.
            unknownFields.mergeField(
                typeId,
                UnknownFieldSet.Field.newBuilder().addLengthDelimited(input.readBytes()).build());
          } else {
            // We already know the type, so we can parse directly from the input
            // with no copying.  Hooray!
            input.readMessage(subBuilder, extensionRegistry);
          }
        } else {
          // Unknown tag.  Skip it.
          if (!input.skipField(tag)) {
            break; // end of group
          }
        }
      }

      input.checkLastTagWas(WireFormat.MESSAGE_SET_ITEM_END_TAG);

      if (subBuilder != null) {
        builder.setField(field, subBuilder.build());
      }
    }
    /**
     * Like {@link #mergeFrom(CodedInputStream, ExtensionRegistryLite)}, but parses a single field.
     *
     * <p>When {@code builder} is not null, the method will parse and merge the field into {@code
     * builder}. Otherwise, it will try to parse the field into {@code extensions}, when it's called
     * by the parsing constructor in generated classes.
     *
     * <p>Package-private because it is used by GeneratedMessage.ExtendableMessage.
     *
     * @param tag The tag, which should have already been read.
     * @return {@code true} unless the tag is an end-group tag.
     */
    static boolean mergeFieldFrom(
        CodedInputStream input,
        UnknownFieldSet.Builder unknownFields,
        ExtensionRegistryLite extensionRegistry,
        Descriptor type,
        Message.Builder builder,
        FieldSet<FieldDescriptor> extensions,
        int tag)
        throws IOException {
      if (type.getOptions().getMessageSetWireFormat() && tag == WireFormat.MESSAGE_SET_ITEM_TAG) {
        mergeMessageSetExtensionFromCodedStream(
            input, unknownFields, extensionRegistry, type, builder, extensions);
        return true;
      }

      final int wireType = WireFormat.getTagWireType(tag);
      final int fieldNumber = WireFormat.getTagFieldNumber(tag);

      final FieldDescriptor field;
      Message defaultInstance = null;

      if (type.isExtensionNumber(fieldNumber)) {
        // extensionRegistry may be either ExtensionRegistry or
        // ExtensionRegistryLite.  Since the type we are parsing is a full
        // message, only a full ExtensionRegistry could possibly contain
        // extensions of it.  Otherwise we will treat the registry as if it
        // were empty.
        if (extensionRegistry instanceof ExtensionRegistry) {
          final ExtensionRegistry.ExtensionInfo extension =
              ((ExtensionRegistry) extensionRegistry).findExtensionByNumber(type, fieldNumber);
          if (extension == null) {
            field = null;
          } else {
            field = extension.descriptor;
            defaultInstance = extension.defaultInstance;
            if (defaultInstance == null
                && field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
              throw new IllegalStateException(
                  "Message-typed extension lacked default instance: " + field.getFullName());
            }
          }
        } else {
          field = null;
        }
      } else if (builder != null) {
        field = type.findFieldByNumber(fieldNumber);
      } else {
        field = null;
      }

      boolean unknown = false;
      boolean packed = false;
      if (field == null) {
        unknown = true; // Unknown field.
      } else if (wireType
          == FieldSet.getWireFormatForFieldType(field.getLiteType(), false /* isPacked */)) {
        packed = false;
      } else if (field.isPackable()
          && wireType
              == FieldSet.getWireFormatForFieldType(field.getLiteType(), true /* isPacked */)) {
        packed = true;
      } else {
        unknown = true; // Unknown wire type.
      }

      if (unknown) { // Unknown field or wrong wire type.  Skip.
        return unknownFields.mergeFieldFrom(tag, input);
      }

      if (packed) {
        final int length = input.readRawVarint32();
        final int limit = input.pushLimit(length);
        if (field.getLiteType() == WireFormat.FieldType.ENUM) {
          while (input.getBytesUntilLimit() > 0) {
            final int rawValue = input.readEnum();
            final Object value = field.getEnumType().findValueByNumber(rawValue);
            if (value == null) {
              // If the number isn't recognized as a valid value for this
              // enum, drop it (don't even add it to unknownFields).
              return true;
            }
            addRepeatedField(builder, extensions, field, value);
          }
        } else {
          while (input.getBytesUntilLimit() > 0) {
            final Object value = FieldSet.readPrimitiveField(input, field.getLiteType());
            addRepeatedField(builder, extensions, field, value);
          }
        }
        input.popLimit(limit);
      } else {
        final Object value;
        switch (field.getType()) {
          case GROUP:
            {
              final Message.Builder subBuilder;
              if (defaultInstance != null) {
                subBuilder = defaultInstance.newBuilderForType();
              } else {
                subBuilder = builder.newBuilderForField(field);
              }
              if (!field.isRepeated()) {
                mergeOriginalMessage(builder, extensions, field, subBuilder);
              }
              input.readGroup(field.getNumber(), subBuilder, extensionRegistry);
              value = subBuilder.buildPartial();
              break;
            }
          case MESSAGE:
            {
              final Message.Builder subBuilder;
              if (defaultInstance != null) {
                subBuilder = defaultInstance.newBuilderForType();
              } else {
                subBuilder = builder.newBuilderForField(field);
              }
              if (!field.isRepeated()) {
                mergeOriginalMessage(builder, extensions, field, subBuilder);
              }
              input.readMessage(subBuilder, extensionRegistry);
              value = subBuilder.buildPartial();
              break;
            }
          case ENUM:
            final int rawValue = input.readEnum();
            value = field.getEnumType().findValueByNumber(rawValue);
            // If the number isn't recognized as a valid value for this enum,
            // drop it.
            if (value == null) {
              unknownFields.mergeVarintField(fieldNumber, rawValue);
              return true;
            }
            break;
          default:
            value = FieldSet.readPrimitiveField(input, field.getLiteType());
            break;
        }

        if (field.isRepeated()) {
          addRepeatedField(builder, extensions, field, value);
        } else {
          setField(builder, extensions, field, value);
        }
      }

      return true;
    }
Пример #19
0
 @Override
 public Builder clearField(Descriptors.FieldDescriptor field) {
   wrappedBuilder.clearField(field);
   return this;
 }
Пример #20
0
 @Override
 public AbstractMessageWrapper buildPartial() {
   return new AbstractMessageWrapper(wrappedBuilder.buildPartial());
 }
Пример #21
0
 @Override
 public Object getRepeatedField(Descriptors.FieldDescriptor field, int index) {
   return wrappedBuilder.getRepeatedField(field, index);
 }
Пример #22
0
 @Override
 public Builder clone() {
   return new Builder(wrappedBuilder.clone());
 }
Пример #23
0
 @Override
 public Builder addRepeatedField(Descriptors.FieldDescriptor field, Object value) {
   wrappedBuilder.addRepeatedField(field, value);
   return this;
 }
Пример #24
0
 @Override
 public Descriptors.Descriptor getDescriptorForType() {
   return wrappedBuilder.getDescriptorForType();
 }
Пример #25
0
 @Override
 public Builder setUnknownFields(UnknownFieldSet unknownFields) {
   wrappedBuilder.setUnknownFields(unknownFields);
   return this;
 }
Пример #26
0
 @Override
 public AbstractMessageWrapper getDefaultInstanceForType() {
   return new AbstractMessageWrapper(wrappedBuilder.getDefaultInstanceForType());
 }
Пример #27
0
 @Override
 public Map<Descriptors.FieldDescriptor, Object> getAllFields() {
   return wrappedBuilder.getAllFields();
 }
Пример #28
0
 public AbstractMessageWrapper build() {
   return new AbstractMessageWrapper(wrappedBuilder.build());
 }