示例#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;
  }
  private static Object readSingleFieldNoTag(
      CodedInputStream input, FieldDescriptor fd, Builder enclosingBuilder) throws IOException {
    switch (fd.getType()) {
      case DOUBLE:
        return input.readDouble();
      case FLOAT:
        return input.readFloat();
      case INT64:
      case UINT64:
        return input.readInt64();
      case INT32:
        return input.readInt32();
      case FIXED64:
        return input.readFixed64();
      case FIXED32:
        return input.readFixed32();
      case BOOL:
        return input.readBool();
      case STRING:
        return input.readString();
      case GROUP:
      case MESSAGE:
        Builder fieldBuilder = enclosingBuilder.newBuilderForField(fd);
        input.readMessage(fieldBuilder, null);
        return fieldBuilder.build();
      case BYTES:
        return input.readBytes();
      case UINT32:
        return input.readUInt32();
      case ENUM:
        EnumValueDescriptor eVal = fd.getEnumType().findValueByNumber(input.readEnum());
        // ideally if a given enum does not exist, we should search
        // unknown fields. but we don't have access to that here. return default
        return eVal != null ? eVal : fd.getDefaultValue();
      case SFIXED32:
        return input.readSFixed32();
      case SFIXED64:
        return input.readSFixed64();
      case SINT32:
        return input.readSInt32();
      case SINT64:
        return input.readSInt64();

      default:
        throw new IllegalArgumentException(
            "Unknown type " + fd.getType() + " for " + fd.getFullName());
    }
  }
示例#3
0
    static void mergeCollection(
        Readable reader,
        ExtensionRegistry extensionRegistry,
        @SuppressWarnings("TypeMayBeWeakened") Builder builder,
        MergeCallback callback)
        throws IOException {
      CharSequence input = toStringBuilder(reader);
      Tokenizer tokenizer = new Tokenizer(input.subSequence(0, input.length()));
      tokenizer.consume(JS_ARRAY_OPEN_STR);
      // Special case of empty list of messages: "[]"
      if (!tokenizer.tryConsume(JS_ARRAY_CLOSE_STR)) {
        // At least one Message present
        do {
          Builder thisBuilder = builder.clone();
          tokenizer.consume("{"); // Needs to happen when the object starts.
          while (!tokenizer.tryConsume("}")) { // Continue till the object is done
            mergeField(tokenizer, extensionRegistry, thisBuilder);
          }
          callback.onMerge(thisBuilder);
          // Iterate if we consume a separator.
        } while (tokenizer.tryConsume(JS_ARRAY_SEP_STR));

        // Make sure the next character terminates the array
        tokenizer.consume(JS_ARRAY_CLOSE_STR);
      }
    }
示例#4
0
 private static Object toJavaObj(
     final Builder builder, final FieldDescriptor fieldDesc, final JsonNode node) {
   Object value;
   switch (fieldDesc.getJavaType()) {
     case MESSAGE:
       final Builder subBuilder = builder.newBuilderForField(fieldDesc);
       value = toProto(subBuilder, node).build();
       break;
     case BOOLEAN:
       value = Boolean.valueOf(node.getBooleanValue());
       break;
     case BYTE_STRING:
       try {
         value = node.getBinaryValue();
       } catch (IOException e) {
         throw new RuntimeException(e);
       }
       break;
     case DOUBLE:
       value = Double.valueOf(node.getDoubleValue());
       break;
     case FLOAT:
       value = Float.valueOf(Double.valueOf(node.getDoubleValue()).floatValue());
       break;
     case ENUM:
       value = fieldDesc.getEnumType().findValueByName(node.getTextValue());
       break;
     case INT:
       value = Integer.valueOf(node.getIntValue());
       break;
     case LONG:
       value = Long.valueOf(node.getLongValue());
       break;
     case STRING:
       value = node.getTextValue();
       break;
     default:
       throw new IllegalArgumentException();
   }
   return value;
 }
示例#5
0
  /**
   * Converts a DataBag into a List of objects with the type in the given FieldDescriptor. DataBags
   * don't map cleanly to repeated protobuf types, so each Tuple has to be unwrapped (by taking the
   * first element if the type is primitive or by converting the Tuple to a Message if the type is
   * MESSAGE), and the contents have to be appended to a List.
   *
   * @param containingMessageBuilder a Message builder for the Message that contains this repeated
   *     field
   * @param fieldDescriptor a FieldDescriptor for this repeated field
   * @param bag the DataBag being serialized
   * @return a protobuf-friendly List of fieldDescriptor-type objects
   */
  public List<Object> dataBagToRepeatedField(
      Builder containingMessageBuilder, FieldDescriptor fieldDescriptor, DataBag bag) {
    ArrayList<Object> bagContents = new ArrayList<Object>((int) bag.size());
    Iterator<Tuple> bagIter = bag.iterator();

    while (bagIter.hasNext()) {
      Tuple tuple = bagIter.next();
      if (fieldDescriptor.getType() == FieldDescriptor.Type.MESSAGE) {
        Builder nestedMessageBuilder = containingMessageBuilder.newBuilderForField(fieldDescriptor);
        bagContents.add(tupleToMessage((Builder) nestedMessageBuilder, tuple));
      } else {
        try {
          bagContents.add(tupleFieldToSingleField(fieldDescriptor, tuple.get(0)));
        } catch (ExecException e) {
          LOG.warn("Could not add a value for repeated field with descriptor " + fieldDescriptor);
        }
      }
    }

    return bagContents;
  }
示例#6
0
  /**
   * Turn a Tuple into a Message with the given type.
   *
   * @param builder a builder for the Message type the tuple will be converted to
   * @param tuple the tuple
   * @return a message representing the given tuple
   */
  public Message tupleToMessage(Builder builder, Tuple tuple) {
    List<FieldDescriptor> fieldDescriptors = builder.getDescriptorForType().getFields();

    if (tuple == null) {
      return builder.build();
    }

    for (int i = 0; i < fieldDescriptors.size() && i < tuple.size(); i++) {
      Object tupleField = null;
      FieldDescriptor fieldDescriptor = fieldDescriptors.get(i);

      try {
        tupleField = tuple.get(i);
      } catch (ExecException e) {
        LOG.warn(
            "Could not convert tuple field "
                + tupleField
                + " to field with descriptor "
                + fieldDescriptor);
        continue;
      }

      if (tupleField != null) {
        if (fieldDescriptor.isRepeated()) {
          // Repeated fields are set with Lists containing objects of the fields' Java type.
          builder.setField(
              fieldDescriptor,
              dataBagToRepeatedField(builder, fieldDescriptor, (DataBag) tupleField));
        } else {
          if (fieldDescriptor.getType() == FieldDescriptor.Type.MESSAGE) {
            Builder nestedMessageBuilder = builder.newBuilderForField(fieldDescriptor);
            builder.setField(
                fieldDescriptor,
                tupleToMessage((Builder) nestedMessageBuilder, (Tuple) tupleField));
          } else {
            builder.setField(fieldDescriptor, tupleFieldToSingleField(fieldDescriptor, tupleField));
          }
        }
      }
    }

    return builder.build();
  }
示例#7
0
 /**
  * Returns a field descriptor for the field of the given builder with the given CAP name. Takes
  * care of differences in casing between CAP and proto.
  *
  * @param builder the builder to search in
  * @param name the CAP name to search for
  * @return the field, or null if it does not exist
  */
 public static FieldDescriptor findFieldByName(Builder builder, String name) {
   return builder == null
       ? null
       : builder.getDescriptorForType().findFieldByName(underscoreCase(name).toLowerCase());
 }
 /**
  * Wrapper around {@link #readFieldNoTag(CodedInputStream, FieldDescriptor, Builder)}. <br>
  * same as <br>
  * <code>
  *  builder.setField(fd, readFieldNoTag(input, fd, builder));  </code>
  */
 public static void setFieldValue(CodedInputStream input, FieldDescriptor fd, Builder builder)
     throws IOException {
   builder.setField(fd, readFieldNoTag(input, fd, builder));
 }