public static Builder builder(Location location) { return new AutoValue_MessageElement.Builder() .location(location) .documentation("") .fields(ImmutableList.<FieldElement>of()) .oneOfs(ImmutableList.<OneOfElement>of()) .nestedTypes(ImmutableList.<TypeElement>of()) .extensions(ImmutableList.<ExtensionsElement>of()) .options(ImmutableList.<OptionElement>of()) .reserveds(ImmutableList.<ReservedElement>of()) .groups(ImmutableList.<GroupElement>of()); }
@Test public void addMultipleExtensions() { ExtensionsElement fives = ExtensionsElement.create(location, 500, 501, ""); ExtensionsElement sixes = ExtensionsElement.create(location, 600, 601, ""); MessageElement element = MessageElement.builder(location) .name("Message") .fields(ImmutableList.of( FieldElement.builder(location) .label(REQUIRED) .type("string") .name("name") .tag(1) .build())) .extensions(ImmutableList.of(fives, sixes)) .build(); assertThat(element.extensions()).hasSize(2); }
@Test public void addMultipleOptions() { FieldElement field = FieldElement.builder(location) .label(REQUIRED) .type("string") .name("name") .tag(1) .build(); OptionElement kitKat = OptionElement.create("kit", Kind.STRING, "kat"); OptionElement fooBar = OptionElement.create("foo", Kind.STRING, "bar"); MessageElement element = MessageElement.builder(location) .name("Message") .fields(ImmutableList.of(field)) .options(ImmutableList.of(kitKat, fooBar)) .build(); assertThat(element.options()).hasSize(2); }
@Test public void simpleWithNestedElementsToSchema() { TypeElement element = MessageElement.builder(location) .name("Message") .fields(ImmutableList.of(FieldElement.builder(location) .label(REQUIRED) .type("string") MessageElement.builder(location) .name("Nested") .fields(ImmutableList.of( FieldElement.builder(location) .label(REQUIRED)
@Test public void defaultFieldWithStringEscapes() throws Exception { String proto = "" + "message Foo {\n" + " optional string name = 1 [\n" + " x = \"\\a\\b\\f\\n\\r\\t\\v\1f\01\001\11\011\111\\xe\\Xe\\xE\\xE\\x41\\X41\"\n" + " ];\n" + "}"; FieldElement field = FieldElement.builder(location.at(2, 3)) .label(OPTIONAL) .type("string") .name("name") .tag(1) .options(ImmutableList.of(OptionElement.create("x", Kind.STRING, "\u0007\b\f\n\r\t\u000b\u0001f\u0001\u0001\u0009\u0009I\u000e\u000e\u000e\u000eAA"))) .build(); assertThat(field.options()).containsOnly(OptionElement.create("x", Kind.STRING, "\u0007\b\f\n\r\t\u000b\u0001f\u0001\u0001\u0009\u0009I\u000e\u000e\u000e\u000eAA")); TypeElement messageElement = MessageElement.builder(location.at(1, 1)) .name("Foo") .fields(ImmutableList.of(field)) .build(); ProtoFileElement expected = ProtoFileElement.builder(location) .types(ImmutableList.of(messageElement)) .build(); assertThat(ProtoParser.parse(location, proto)) .isEqualTo(expected); }
@Test public void defaultFieldWithParen() throws Exception { String proto = "" + "message Foo {\n" + " optional string claim_token = 2 [(squareup.redacted) = true];\n" + "}"; FieldElement field = FieldElement.builder(location.at(2, 3)) .label(OPTIONAL) .type("string") .name("claim_token") .tag(2) .options(ImmutableList.of( OptionElement.create("squareup.redacted", Kind.BOOLEAN, "true", true))) .build(); assertThat(field.options()).containsOnly( OptionElement.create("squareup.redacted", Kind.BOOLEAN, "true", true)); TypeElement messageElement = MessageElement.builder(location.at(1, 1)) .name("Foo") .fields(ImmutableList.of(field)) .build(); ProtoFileElement expected = ProtoFileElement.builder(location) .types(ImmutableList.of(messageElement)) .build(); assertThat(ProtoParser.parse(location, proto)) .isEqualTo(expected); }
@Test public void hexTag() throws Exception { String proto = "" + "message HexTag {\n" + " required string hex = 0x10;\n" + " required string uppercase_x_hex = 0X11;\n" + "}"; ProtoFileElement expected = ProtoFileElement.builder(location) .types(ImmutableList.<TypeElement>of( MessageElement.builder(location.at(1, 1)) .name("HexTag") .fields(ImmutableList.of( FieldElement.builder(location.at(2, 3)) .label(REQUIRED) .type("string") .name("hex") .tag(16) .build(), FieldElement.builder(location.at(3, 3)) .label(REQUIRED) .type("string") .name("uppercase_x_hex") .tag(17) .build())) .build())) .build(); assertThat(ProtoParser.parse(location, proto)).isEqualTo(expected); }
@Test public void proto3MessageFieldsDoNotRequireLabels() throws Exception { String proto = "" + "syntax = \"proto3\";\n" + "message Message {\n" + " string a = 1;\n" + " int32 b = 2;\n" + "}"; ProtoFileElement expected = ProtoFileElement.builder(location) .syntax(ProtoFile.Syntax.PROTO_3) .types(ImmutableList.<TypeElement>of( MessageElement.builder(location.at(2, 1)) .name("Message") .fields(ImmutableList.of( FieldElement.builder(location.at(3, 3)) .type("string") .name("a") .tag(1) .build(), FieldElement.builder(location.at(4, 3)) .type("int32") .name("b") .tag(2) .build())) .build())) .build(); assertThat(ProtoParser.parse(location, proto)).isEqualTo(expected); }
/** It looks like an option, but 'default' is special. It's missing from descriptor.proto! */ @Test public void defaultFieldOptionIsSpecial() { String proto = "" + "message Message {\n" + " required string a = 1 [default = \"b\", faulted = \"c\"];\n" + "}\n"; ProtoFileElement expected = ProtoFileElement.builder(location) .types(ImmutableList.<TypeElement>of( MessageElement.builder(location.at(1, 1)) .name("Message") .fields(ImmutableList.of( FieldElement.builder(location.at(2, 3)) .label(REQUIRED) .type("string") .name("a") .defaultValue("b") .options(ImmutableList.of( OptionElement.create("faulted", Kind.STRING, "c"))) .tag(1) .build())) .build())) .build(); assertThat(ProtoParser.parse(location, proto)).isEqualTo(expected); }
@Test public void proto3MessageFieldsPermitRepeated() throws Exception { String proto = "" + "syntax = \"proto3\";\n" + "message Message {\n" + " repeated string a = 1;\n" + "}"; ProtoFileElement expected = ProtoFileElement.builder(location) .syntax(ProtoFile.Syntax.PROTO_3) .types(ImmutableList.<TypeElement>of( MessageElement.builder(location.at(2, 1)) .name("Message") .fields(ImmutableList.of( FieldElement.builder(location.at(3, 3)) .label(REPEATED) .type("string") .name("a") .tag(1) .build())) .build())) .build(); assertThat(ProtoParser.parse(location, proto)).isEqualTo(expected); }
@Test public void simpleWithOptionsToSchema() { FieldElement field = FieldElement.builder(location) .label(REQUIRED) .type("string") .name("name") .tag(1) .build(); TypeElement element = MessageElement.builder(location) .name("Message") .fields(ImmutableList.of(field)) .options(ImmutableList.of( OptionElement.create("kit", Kind.STRING, "kat"))) .build(); String expected = "" + "message Message {\n" + " option kit = \"kat\";\n" + "\n" + " required string name = 1;\n" + "}\n"; assertThat(element.toSchema()).isEqualTo(expected); }
@Test public void stringWithSingleQuotes() { String proto = "" + "message Foo {\n" + " optional string name = 1 [default = 'single\"quotes'];\n" + "}"; FieldElement field = FieldElement.builder(location.at(2, 3)) .label(OPTIONAL) .type("string") .name("name") .tag(1) .defaultValue("single\"quotes") .build(); TypeElement messageElement = MessageElement.builder(location.at(1, 1)) .name("Foo") .fields(ImmutableList.of(field)) .build(); ProtoFileElement expected = ProtoFileElement.builder(location) .types(ImmutableList.of(messageElement)) .build(); assertThat(ProtoParser.parse(location, proto)).isEqualTo(expected); }
@Test public void simpleWithDocumentationToSchema() { TypeElement element = MessageElement.builder(location) .name("Message") .documentation("Hello") .fields(ImmutableList.of( FieldElement.builder(location) .label(REQUIRED) .type("string") .name("name") .tag(1) .build())) .build(); String expected = "" + "// Hello\n" + "message Message {\n" + " required string name = 1;\n" + "}\n"; assertThat(element.toSchema()).isEqualTo(expected); }
@Test public void simpleWithExtensionsToSchema() { TypeElement element = MessageElement.builder(location) .name("Message") .fields(ImmutableList.of(FieldElement.builder(location) .label(REQUIRED) .type("string") .name("name") .tag(1) .build())) .extensions(ImmutableList.of( ExtensionsElement.create(location, 500, 501, ""))) .build(); String expected = "" + "message Message {\n" + " required string name = 1;\n" + "\n" + " extensions 500 to 501;\n" + "}\n"; assertThat(element.toSchema()).isEqualTo(expected); }
@Test public void adjacentStringsConcatenated() { String proto = "" + "message Foo {\n" + " optional string name = 1 [\n" + " default = \"concat \"\n" + " 'these '\n" + " \"please\"\n" + " ];\n" + "}"; FieldElement field = FieldElement.builder(location.at(2, 3)) .label(OPTIONAL) .type("string") .name("name") .tag(1) .defaultValue("concat these please") .build(); TypeElement messageElement = MessageElement.builder(location.at(1, 1)) .name("Foo") .fields(ImmutableList.of(field)) .build(); ProtoFileElement expected = ProtoFileElement.builder(location) .types(ImmutableList.of(messageElement)) .build(); assertThat(ProtoParser.parse(location, proto)).isEqualTo(expected); }
@Test public void addMultipleFields() { FieldElement firstName = FieldElement.builder(location) .label(REQUIRED) .type("string") .name("first_name") .tag(1) .build(); FieldElement lastName = FieldElement.builder(location) .label(REQUIRED) .type("string") .name("last_name") .tag(2) .build(); MessageElement element = MessageElement.builder(location) .name("Message") .fields(ImmutableList.of(firstName, lastName)) .build(); assertThat(element.fields()).hasSize(2); }
@Test public void simpleToSchema() { TypeElement element = MessageElement.builder(location) .name("Message") .fields(ImmutableList.of( FieldElement.builder(location) .label(REQUIRED) .type("string") .name("name") .tag(1) .build())) .build(); String expected = "" + "message Message {\n" + " required string name = 1;\n" + "}\n"; assertThat(element.toSchema()).isEqualTo(expected); }
@Test public void noWhitespace() { String proto = "message C {optional A.B ab = 1;}"; ProtoFileElement expected = ProtoFileElement.builder(location) .types(ImmutableList.<TypeElement>of( MessageElement.builder(location.at(1, 1)) .name("C").fields(ImmutableList.of(FieldElement.builder(location.at(1, 12)) .label(OPTIONAL) .type("A.B") .name("ab") .tag(1) .build())) .build())) .build(); assertThat(ProtoParser.parse(location, proto)).isEqualTo(expected); } }
@Test public void addMultipleTypes() { TypeElement nested1 = MessageElement.builder(location).name("Nested1").build(); TypeElement nested2 = MessageElement.builder(location).name("Nested2").build(); TypeElement element = MessageElement.builder(location) .name("Message") .fields(ImmutableList.of(FieldElement.builder(location) .label(REQUIRED) .type("string") .name("name") .tag(1) .build())) .nestedTypes(ImmutableList.of(nested1, nested2)) .build(); assertThat(element.nestedTypes()).hasSize(2); }
MessageElement toElement() { return MessageElement.builder(location) .documentation(documentation) .name(name) .options(options.toElements()) .fields(Field.toElements(declaredFields)) .nestedTypes(Type.toElements(nestedTypes)) .oneOfs(OneOf.toElements(oneOfs)) .extensions(Extensions.toElements(extensionsList)) .reserveds(Reserved.toElements(reserveds)) .build(); } }