Beispiel #1
0
 /**
  * Reads and discards a single field, given its tag value.
  *
  * @return {@code false} if the tag is an endgroup tag, in which case nothing is skipped.
  *     Otherwise, returns {@code true}.
  */
 public boolean skipField(final int tag) throws IOException {
   switch (WireFormat.getTagWireType(tag)) {
     case WireFormat.WIRETYPE_VARINT:
       skipRawVarint();
       return true;
     case WireFormat.WIRETYPE_FIXED64:
       skipRawBytes(8);
       return true;
     case WireFormat.WIRETYPE_LENGTH_DELIMITED:
       skipRawBytes(readRawVarint32());
       return true;
     case WireFormat.WIRETYPE_START_GROUP:
       skipMessage();
       checkLastTagWas(
           WireFormat.makeTag(WireFormat.getTagFieldNumber(tag), WireFormat.WIRETYPE_END_GROUP));
       return true;
     case WireFormat.WIRETYPE_END_GROUP:
       return false;
     case WireFormat.WIRETYPE_FIXED32:
       skipRawBytes(4);
       return true;
     default:
       throw InvalidProtocolBufferException.invalidWireType();
   }
 }
Beispiel #2
0
 private static void printUnknownFieldValue(final int tag,
                                            final Object value,
                                            final TextGenerator generator)
                                            throws IOException {
   switch (WireFormat.getTagWireType(tag)) {
     case WireFormat.WIRETYPE_VARINT:
       generator.print(unsignedToString((Long) value));
       break;
     case WireFormat.WIRETYPE_FIXED32:
       generator.print(
           String.format((Locale) null, "0x%08x", (Integer) value));
       break;
     case WireFormat.WIRETYPE_FIXED64:
       generator.print(String.format((Locale) null, "0x%016x", (Long) value));
       break;
     case WireFormat.WIRETYPE_LENGTH_DELIMITED:
       generator.print("\"");
       generator.print(escapeBytes((ByteString) value));
       generator.print("\"");
       break;
     case WireFormat.WIRETYPE_START_GROUP:
       DEFAULT_PRINTER.printUnknownFields((UnknownFieldSet) value, generator);
       break;
     default:
       throw new IllegalArgumentException("Bad tag: " + tag);
   }
 }
  public int readFieldNumber(Schema schema) throws IOException {
    final int fieldNumber = input.readFieldNumber(schema);
    if (WireFormat.getTagWireType(((CodedInput) input).getLastTag())
        == WireFormat.WIRETYPE_REFERENCE) {
      // a reference.
      lastRef = input.readUInt32();
      messageReference = true;
    } else {
      // always unset.
      messageReference = false;
    }

    return fieldNumber;
  }
Beispiel #4
0
 /**
  * Reads a single field and writes it to output in wire format, given its tag value.
  *
  * @return {@code false} if the tag is an endgroup tag, in which case nothing is skipped.
  *     Otherwise, returns {@code true}.
  */
 public boolean skipField(final int tag, final CodedOutputStream output) throws IOException {
   switch (WireFormat.getTagWireType(tag)) {
     case WireFormat.WIRETYPE_VARINT:
       {
         long value = readInt64();
         output.writeRawVarint32(tag);
         output.writeUInt64NoTag(value);
         return true;
       }
     case WireFormat.WIRETYPE_FIXED64:
       {
         long value = readRawLittleEndian64();
         output.writeRawVarint32(tag);
         output.writeFixed64NoTag(value);
         return true;
       }
     case WireFormat.WIRETYPE_LENGTH_DELIMITED:
       {
         ByteString value = readBytes();
         output.writeRawVarint32(tag);
         output.writeBytesNoTag(value);
         return true;
       }
     case WireFormat.WIRETYPE_START_GROUP:
       {
         output.writeRawVarint32(tag);
         skipMessage(output);
         int endtag =
             WireFormat.makeTag(WireFormat.getTagFieldNumber(tag), WireFormat.WIRETYPE_END_GROUP);
         checkLastTagWas(endtag);
         output.writeRawVarint32(endtag);
         return true;
       }
     case WireFormat.WIRETYPE_END_GROUP:
       {
         return false;
       }
     case WireFormat.WIRETYPE_FIXED32:
       {
         int value = readRawLittleEndian32();
         output.writeRawVarint32(tag);
         output.writeFixed32NoTag(value);
         return true;
       }
     default:
       throw InvalidProtocolBufferException.invalidWireType();
   }
 }
    /**
     * 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;
    }
Beispiel #6
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;
    }
    /**
     * Called by subclasses to parse an unknown field or an extension.
     *
     * @return {@code true} unless the tag is an end-group tag.
     */
    @Override
    protected boolean parseUnknownField(
        final CodedInputStream input, final ExtensionRegistryLite extensionRegistry, final int tag)
        throws IOException {
      final FieldSet<ExtensionDescriptor> extensions =
          ((ExtendableMessage) internalGetResult()).extensions;

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

      final GeneratedExtension<MessageType, ?> extension =
          extensionRegistry.findLiteExtensionByNumber(getDefaultInstanceForType(), fieldNumber);

      boolean unknown = false;
      boolean packed = false;
      if (extension == null) {
        unknown = true; // Unknown field.
      } else if (wireType
          == FieldSet.getWireFormatForFieldType(
              extension.descriptor.getLiteType(), false /* isPacked */)) {
        packed = false; // Normal, unpacked value.
      } else if (extension.descriptor.isRepeated
          && extension.descriptor.type.isPackable()
          && wireType
              == FieldSet.getWireFormatForFieldType(
                  extension.descriptor.getLiteType(), true /* isPacked */)) {
        packed = true; // Packed value.
      } else {
        unknown = true; // Wrong wire type.
      }

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

      if (packed) {
        final int length = input.readRawVarint32();
        final int limit = input.pushLimit(length);
        if (extension.descriptor.getLiteType() == WireFormat.FieldType.ENUM) {
          while (input.getBytesUntilLimit() > 0) {
            final int rawValue = input.readEnum();
            final Object value = extension.descriptor.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;
            }
            extensions.addRepeatedField(extension.descriptor, value);
          }
        } else {
          while (input.getBytesUntilLimit() > 0) {
            final Object value =
                FieldSet.readPrimitiveField(input, extension.descriptor.getLiteType());
            extensions.addRepeatedField(extension.descriptor, value);
          }
        }
        input.popLimit(limit);
      } else {
        final Object value;
        switch (extension.descriptor.getLiteJavaType()) {
          case MESSAGE:
            {
              MessageLite.Builder subBuilder = null;
              if (!extension.descriptor.isRepeated()) {
                MessageLite existingValue = (MessageLite) extensions.getField(extension.descriptor);
                if (existingValue != null) {
                  subBuilder = existingValue.toBuilder();
                }
              }
              if (subBuilder == null) {
                subBuilder = extension.messageDefaultInstance.newBuilderForType();
              }
              if (extension.descriptor.getLiteType() == WireFormat.FieldType.GROUP) {
                input.readGroup(extension.getNumber(), subBuilder, extensionRegistry);
              } else {
                input.readMessage(subBuilder, extensionRegistry);
              }
              value = subBuilder.build();
              break;
            }
          case ENUM:
            final int rawValue = input.readEnum();
            value = extension.descriptor.getEnumType().findValueByNumber(rawValue);
            // If the number isn't recognized as a valid value for this enum,
            // drop it.
            if (value == null) {
              return true;
            }
            break;
          default:
            value = FieldSet.readPrimitiveField(input, extension.descriptor.getLiteType());
            break;
        }

        if (extension.descriptor.isRepeated()) {
          extensions.addRepeatedField(extension.descriptor, value);
        } else {
          extensions.setField(extension.descriptor, value);
        }
      }

      return true;
    }