예제 #1
0
  /**
   * Assigns all fields in {@link JsonNode} instance to a {@link Builder}.
   *
   * @param builder the builder to be populated
   * @param root the JSON object
   * @return the original builder, populated with any fields that were discovered
   */
  public static Builder toProto(final Builder builder, final JsonNode root) {
    Descriptor type = builder.getDescriptorForType();
    for (final FieldDescriptor fieldDesc : type.getFields()) {
      final String attrName = fieldDesc.getName();
      final JsonNode node = root.get(attrName);

      if (node == null) {
        continue;
      }

      if (node.isNull()) {
        continue;
      }

      if (fieldDesc.isRepeated()) {
        final Iterator<JsonNode> iter = node.getElements();
        while (iter.hasNext()) {
          builder.addRepeatedField(fieldDesc, toJavaObj(builder, fieldDesc, iter.next()));
        }
      } else {
        builder.setField(fieldDesc, toJavaObj(builder, fieldDesc, node));
      }
    }
    return builder;
  }
예제 #2
0
 private static void getRepeatedFieldNamesInternal(Descriptor d, Map<String, Set<String>> result) {
   Set<String> repeatedFields = Sets.newHashSet();
   for (FieldDescriptor fd : d.getFields()) {
     if (fd.isRepeated()) {
       repeatedFields.add(javaCase(fd.getName()));
     }
     if (fd.getType() == FieldDescriptor.Type.MESSAGE) {
       getRepeatedFieldNamesInternal(fd.getMessageType(), result);
     }
   }
   if (!repeatedFields.isEmpty()) {
     result.put(javaCase(d.getName()), repeatedFields);
   }
 }
예제 #3
0
 public static List<String> getMessageFieldNames(
     Descriptor descriptor, Map<String, String> fieldNameTranslations) {
   Function<FieldDescriptor, String> fieldTransformer =
       getFieldTransformerFor(fieldNameTranslations);
   return ListHelper.filter(
       Lists.transform(descriptor.getFields(), fieldTransformer), Predicates.<String>notNull());
 }
예제 #4
0
 /** Get a {@code DynamicMessage} representing the default instance of the given type. */
 public static DynamicMessage getDefaultInstance(Descriptor type) {
   int oneofDeclCount = type.toProto().getOneofDeclCount();
   FieldDescriptor[] oneofCases = new FieldDescriptor[oneofDeclCount];
   return new DynamicMessage(
       type,
       FieldSet.<FieldDescriptor>emptySet(),
       oneofCases,
       UnknownFieldSet.getDefaultInstance());
 }
 public void writeTo(CodedOutputStream output) throws IOException {
   if (type.getOptions().getMessageSetWireFormat()) {
     fields.writeMessageSetTo(output);
     unknownFields.writeAsMessageSetTo(output);
   } else {
     fields.writeTo(output);
     unknownFields.writeTo(output);
   }
 }
예제 #6
0
 /**
  * Recursively checks whether the specified class uses any Protocol Buffers fields that cannot be
  * deterministically encoded.
  *
  * @throws NonDeterministicException if the object cannot be encoded deterministically.
  */
 static void verifyDeterministic(ProtoCoder<?> coder) throws NonDeterministicException {
   Class<? extends Message> message = coder.getMessageType();
   ExtensionRegistry registry = coder.getExtensionRegistry();
   Set<Descriptor> descriptors = getRecursiveDescriptorsForClass(message, registry);
   for (Descriptor d : descriptors) {
     for (FieldDescriptor fd : d.getFields()) {
       // If there is a transitively reachable Protocol Buffers map field, then this object cannot
       // be encoded deterministically.
       if (fd.isMapField()) {
         String reason =
             String.format(
                 "Protocol Buffers message %s transitively includes Map field %s (from file %s)."
                     + " Maps cannot be deterministically encoded.",
                 message.getName(), fd.getFullName(), fd.getFile().getFullName());
         throw new NonDeterministicException(coder, reason);
       }
     }
   }
 }
예제 #7
0
  static boolean isInitialized(Descriptor type, FieldSet<FieldDescriptor> fields) {
    // Check that all required fields are present.
    for (final FieldDescriptor field : type.getFields()) {
      if (field.isRequired()) {
        if (!fields.hasField(field)) {
          return false;
        }
      }
    }

    // Check that embedded messages are initialized.
    return fields.isInitialized();
  }
예제 #8
0
  private static void recursivelyAddDescriptors(
      Descriptor message, Set<Descriptor> descriptors, ExtensionRegistry registry) {
    if (descriptors.contains(message)) {
      return;
    }
    descriptors.add(message);

    for (FieldDescriptor f : message.getFields()) {
      recursivelyAddDescriptors(f, descriptors, registry);
    }
    for (FieldDescriptor f : message.getExtensions()) {
      recursivelyAddDescriptors(f, descriptors, registry);
    }
    for (ExtensionInfo info :
        registry.getAllImmutableExtensionsByExtendedType(message.getFullName())) {
      recursivelyAddDescriptors(info.descriptor, descriptors, registry);
    }
    for (ExtensionInfo info :
        registry.getAllMutableExtensionsByExtendedType(message.getFullName())) {
      recursivelyAddDescriptors(info.descriptor, descriptors, registry);
    }
  }
  public int getSerializedSize() {
    int size = memoizedSize;
    if (size != -1) return size;

    if (type.getOptions().getMessageSetWireFormat()) {
      size = fields.getMessageSetSerializedSize();
      size += unknownFields.getSerializedSizeAsMessageSet();
    } else {
      size = fields.getSerializedSize();
      size += unknownFields.getSerializedSize();
    }

    memoizedSize = size;
    return size;
  }
예제 #10
0
 /** Construct a {@code Builder} for the given type. */
 private Builder(Descriptor type) {
   this.type = type;
   this.fields = FieldSet.newFieldSet();
   this.unknownFields = UnknownFieldSet.getDefaultInstance();
   this.oneofCases = new FieldDescriptor[type.toProto().getOneofDeclCount()];
 }
    /**
     * 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;
    }
예제 #12
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;
    }