/** Returns the type to import for {@code type}. */ private @Nullable ProtoType importedType(ProtoType type) { // Map key type is always scalar. if (type.isMap()) type = type.valueType(); return type.isScalar() ? null : type; }
private void mark(ProtoType type) { // Mark the map type as it's non-scalar and transitively reachable. if (type.isMap()) { marks.mark(type); // Map key type is always scalar. No need to mark it. type = type.valueType(); } if (marks.mark(type)) { queue.add(type); // The transitive dependencies of this type must be visited. } }
private TypeName fieldType(Field field) { ProtoType type = field.type(); if (type.isMap()) { return ParameterizedTypeName.get(ClassName.get(Map.class), typeName(type.keyType()), typeName(type.valueType())); } TypeName messageType = typeName(type); return field.isRepeated() ? listOf(messageType) : messageType; }
.initializer("$T.newMapAdapter($L, $L)", ADAPTER, singleAdapterFor(field.type().keyType()), singleAdapterFor(field.type().valueType())) .build());
Field retainAll(Schema schema, MarkSet markSet) { // For map types only the value can participate in pruning as the key will always be scalar. if (type.isMap() && !markSet.contains(type.valueType())) return null; if (!markSet.contains(type)) return null; Field result = new Field(packageName, location, label, name, documentation, tag, defaultValue, elementType, options.retainAll(schema, markSet), extension); result.type = type; result.deprecated = deprecated; result.packed = packed; result.redacted = redacted; return result; }
void validateImport(Location location, ProtoType type) { // Map key type is always scalar. No need to validate it. if (type.isMap()) type = type.valueType(); if (type.isScalar()) return; String path = location.path(); String requiredImport = get(type).location().path(); if (!path.equals(requiredImport) && !imports.containsEntry(path, requiredImport)) { addError("%s needs to import %s", path, requiredImport); } }
@Test public void linkMessage() throws Exception { Schema schema = new RepoBuilder() .add("message.proto", "" + "import \"foo.proto\";\n" + "message Message {\n" + " optional foo_package.Foo field = 1;\n" + " map<string, foo_package.Bar> bars = 2;\n" + "}\n") .add("foo.proto", "" + "package foo_package;\n" + "message Foo {\n" + "}\n" + "message Bar {\n" + "}\n") .schema(); MessageType message = (MessageType) schema.getType("Message"); Field field = message.field("field"); assertThat(field.type()).isEqualTo(schema.getType("foo_package.Foo").type()); ProtoType bars = message.field("bars").type(); assertThat(bars.keyType()).isEqualTo(ProtoType.STRING); assertThat(bars.valueType()).isEqualTo(schema.getType("foo_package.Bar").type()); }
@Test public void fieldMapTypeImported() throws Exception { Schema schema = new RepoBuilder() .add("a.proto", "" + "package pa;\n" + "import \"b.proto\";\n" + "message A {\n" + " map<string, pb.B> b = 1;\n" + "}\n") .add("b.proto", "" + "package pb;\n" + "message B {\n" + "}\n") .schema(); MessageType a = (MessageType) schema.getType("pa.A"); MessageType b = (MessageType) schema.getType("pb.B"); assertThat(a.field("b").type().valueType()).isEqualTo(b.type()); }
private ProtoType resolveType(String name, boolean messageOnly) { ProtoType type = ProtoType.get(name); if (type.isScalar()) { if (messageOnly) { addError("expected a message but was %s", name); } return type; } if (type.isMap()) { if (messageOnly) { addError("expected a message but was %s", name); } ProtoType keyType = resolveType(type.keyType().toString(), false); ProtoType valueType = resolveType(type.valueType().toString(), false); return new ProtoType(keyType, valueType, name); } Type resolved = resolve(name, protoTypeNames); if (resolved == null) { addError("unable to resolve %s", name); return ProtoType.BYTES; // Just return any placeholder. } if (messageOnly && !(resolved instanceof MessageType)) { addError("expected a message but was %s", name); return ProtoType.BYTES; // Just return any placeholder. } return resolved.type(); }
private AnnotationSpec wireFieldAnnotation(Field field) { AnnotationSpec.Builder result = AnnotationSpec.builder(WireField.class); int tag = field.tag(); result.addMember("tag", String.valueOf(tag)); if (field.type().isMap()) { result.addMember("keyAdapter", "$S", adapterString(field.type().keyType())); result.addMember("adapter", "$S", adapterString(field.type().valueType())); } else { result.addMember("adapter", "$S", adapterString(field.type())); } if (!field.isOptional()) { if (field.isPacked()) { result.addMember("label", "$T.PACKED", WireField.Label.class); } else if (field.label() != null) { result.addMember("label", "$T.$L", WireField.Label.class, field.label()); } } if (field.isRedacted()) { result.addMember("redacted", "true"); } return result.build(); }
private void mark(ProtoType type) { // Map key type is always scalar. No need to mark it. if (type.isMap()) type = type.valueType(); if (marks.mark(type)) { queue.add(type); // The transitive dependencies of this type must be visited. } }
/** Returns the type to import for {@code type}. */ private ProtoType importedType(ProtoType type) { // Map key type is always scalar. if (type.isMap()) { type = type.valueType(); } return type.isScalar() ? null : type; }
private String getTypeString(ProtoType type) { checkNotNull(type); if (type.isScalar()) { return type.toString(); } else if (type.isMap()) { return type.valueType().toString(); } else if (isEnum(type)) { return "enum"; } else { return "message"; } }
Field retainAll(Schema schema, MarkSet markSet) { // For map types only the value can participate in pruning as the key will always be scalar. if (type.isMap() && !markSet.contains(type.valueType())) return null; if (!markSet.contains(type)) return null; Field result = new Field(packageName, location, label, name, documentation, tag, defaultValue, elementType, options.retainAll(schema, markSet), extension); result.type = type; result.deprecated = deprecated; result.packed = packed; result.redacted = redacted; return result; }
Field retainAll(Schema schema, MarkSet markSet) { // For map types only the value can participate in pruning as the key will always be scalar. if (type.isMap() && !markSet.contains(type.valueType())) return null; if (!markSet.contains(type)) return null; Field result = new Field(packageName, location, label, name, documentation, tag, defaultValue, elementType, options.retainAll(schema, markSet), extension); result.type = type; result.deprecated = deprecated; result.packed = packed; result.redacted = redacted; return result; }
void validateImport(Location location, ProtoType type) { // Map key type is always scalar. No need to validate it. if (type.isMap()) type = type.valueType(); if (type.isScalar()) return; String path = location.path(); String requiredImport = get(type).location().path(); if (!path.equals(requiredImport) && !imports.containsEntry(path, requiredImport)) { addError("%s needs to import %s", path, requiredImport); } }
void validateImport(Location location, ProtoType type) { // Map key type is always scalar. No need to validate it. if (type.isMap()) type = type.valueType(); if (type.isScalar()) return; String path = location.path(); String requiredImport = get(type).location().path(); if (!path.equals(requiredImport) && !imports.containsEntry(path, requiredImport)) { addError("%s needs to import %s", path, requiredImport); } }
private TypeName fieldType(Field field) { ProtoType type = field.type(); if (type.isMap()) { return ParameterizedTypeName.get(ClassName.get(Map.class), typeName(type.keyType()), typeName(type.valueType())); } TypeName messageType = typeName(type); if (messageType.equals(BYTE_STRING)) { messageType = ArrayTypeName.of(byte.class); } return field.isRepeated() ? listOf(messageType) : messageType; }
public Schema getSchemaByType(ProtoType protoType) { if (protoType.isScalar()) { return SchemaUtil.getSchema(protoType, this); } else if (protoType.isMap()) { return new Schema().additionalProperties(getSchemaByType(protoType.valueType())).type("object"); } else { return new Schema().$ref(getRefer(protoType)); } } }