Exemple #1
0
  @Test
  public void structuredAndUnstructuredOptions() throws Exception {
    // From https://developers.google.com/protocol-buffers/docs/proto#options
    Schema schema =
        new SchemaBuilder()
            .add(
                "foo.proto",
                ""
                    + "import \"google/protobuf/descriptor.proto\";\n"
                    + "message FooOptions {\n"
                    + "  optional int32 opt1 = 1;\n"
                    + "  optional string opt2 = 2;\n"
                    + "}\n"
                    + "\n"
                    + "extend google.protobuf.FieldOptions {\n"
                    + "  optional FooOptions foo_options = 1234;\n"
                    + "}\n"
                    + "\n"
                    + "message Bar {\n"
                    + "  optional int32 a = 1 [(foo_options).opt1 = 123, (foo_options).opt2 = \"baz\"];\n"
                    + "  optional int32 b = 2 [(foo_options) = { opt1: 456 opt2: \"quux\" }];\n"
                    + "}\n")
            .add("google/protobuf/descriptor.proto")
            .build();

    ProtoMember fooOptions = ProtoMember.get(Options.FIELD_OPTIONS, "foo_options");
    ProtoMember opt1 = ProtoMember.get(ProtoType.get("FooOptions"), "opt1");
    ProtoMember opt2 = ProtoMember.get(ProtoType.get("FooOptions"), "opt2");

    MessageType bar = (MessageType) schema.getType("Bar");
    assertThat(bar.field("a").options().map())
        .isEqualTo(ImmutableMap.of(fooOptions, ImmutableMap.of(opt1, "123", opt2, "baz")));
    assertThat(bar.field("b").options().map())
        .isEqualTo(ImmutableMap.of(fooOptions, ImmutableMap.of(opt1, "456", opt2, "quux")));
  }
Exemple #2
0
  Map<ProtoMember, Object> canonicalizeOption(
      Linker linker, ProtoType extensionType, OptionElement option) {
    Type type = linker.get(extensionType);
    if (!(type instanceof MessageType)) {
      return null; // No known extensions for the given extension type.
    }
    MessageType messageType = (MessageType) type;

    String[] path;
    Field field = messageType.field(option.name());
    if (field != null) {
      // This is an option declared by descriptor.proto.
      path = new String[] {option.name()};
    } else {
      // This is an option declared by an extension.
      Map<String, Field> extensionsForType = messageType.extensionFieldsMap();

      path = resolveFieldPath(option.name(), extensionsForType.keySet());
      String packageName = linker.packageName();
      if (path == null && packageName != null) {
        // If the path couldn't be resolved, attempt again by prefixing it with the package name.
        path = resolveFieldPath(packageName + "." + option.name(), extensionsForType.keySet());
      }
      if (path == null) {
        return null; // Unable to find the root of this field path.
      }

      field = extensionsForType.get(path[0]);
    }

    Map<ProtoMember, Object> result = new LinkedHashMap<>();
    Map<ProtoMember, Object> last = result;
    ProtoType lastProtoType = messageType.type();
    for (int i = 1; i < path.length; i++) {
      Map<ProtoMember, Object> nested = new LinkedHashMap<>();
      last.put(ProtoMember.get(lastProtoType, field), nested);
      lastProtoType = field.type();
      last = nested;
      field = linker.dereference(field, path[i]);
      if (field == null) {
        return null; // Unable to dereference this path segment.
      }
    }

    last.put(
        ProtoMember.get(lastProtoType, field), canonicalizeValue(linker, field, option.value()));
    return result;
  }