skip to Main Content

I have a .proto file and would like to change it to JSON schema by using Java and its libraries. What are the steps I should consider?

I have tried to get the protobuffer and understand the filedescriptor which is not providing meaningful information until you build the schema.

2

Answers


  1. Chosen as BEST ANSWER

    convert .proto to .pb file or use the proto generated java classes to get the Descriptor object.

    public static void main(String[] args) {
            DescriptorProtos.FileDescriptorSet fileDescriptorSet = DescriptorProtos.FileDescriptorSet.parseFrom(ProtoToJsonSchemaConverter.class.getClassLoader().getResourceAsStream("desc.pb"));
    
    //get the Descriptors.Descriptor object from DescriptorProtos.FileDescriptorSet 
    
    // use the generated class to get the Descriptor object
    Descriptors.Descriptor descriptor = TestMessageProtos.testMessage.getDescriptor();
    
            
    String schema = translateProtoToJsonSchema(descriptor.getFile().toProto());
    }
     String translateProtoToJsonSchema(DescriptorProtos.FileDescriptorProto fileDescriptorProto) {
          
            StringBuilder jsonSchema = new StringBuilder();
            jsonSchema.append("{n");
            jsonSchema.append("  "type": "object",n");
            jsonSchema.append("  "properties": {n");
    
            for (DescriptorProtos.DescriptorProto message : fileDescriptorProto.getMessageTypeList()) {
                jsonSchema.append("    "" + message.getName() + "": {n");
                jsonSchema.append("      "type": "object",n");
                jsonSchema.append("      "properties": {n");
    
                for (DescriptorProtos.FieldDescriptorProto field : message.getFieldList()) {
                    jsonSchema.append("        "" + field.getName() + "": {n");
                    jsonSchema.append("          "type": "" + fieldTypeToJsonSchemaType(field.getType()) + ""n");
                    jsonSchema.append("        },n");
                }
    
                jsonSchema.append("      }n");
                jsonSchema.append("    },n");
            }
    
            jsonSchema.append("  }n");
            jsonSchema.append("}");
    
            return jsonSchema.toString();
        }
       String fieldTypeToJsonSchemaType(DescriptorProtos.FieldDescriptorProto.Type fieldType) {
           
            switch (fieldType) {
                case TYPE_STRING:
                    return "string";
                case TYPE_INT32:
                case TYPE_INT64:
                    return "integer";
                case TYPE_DOUBLE:
                    return "number";
                case TYPE_BOOL:
                    return "boolean";
                // Add more cases for other types as needed
                default:
                    return "unknown";
            }
        }
    
    

  2. The thing I’m wondering is why one would ever need to do that?!

    The Protobuf schema file is for the description of data, and one can generate classes that represent that data in pretty much any language one wants (including Java). These classes can serialise the data to/from Protobuf’s binary wireformat as well as it’s own dialect of JSON, validating the data content as they do so (i.e. the data contains the right fields of the right types with the right identity and structure).

    A JSON schema can also be used to validate JSON data, or possibly also used for code generation too. Doing so simply duplicates what you can already do with the Protobuf schema and the tools / libraries associated with it. So, converting the Protobuf schema to a JSON schema feels like it’s not really getting you anywhere; so far as I can see, you’ll get no new functionality from having done so.

    There is an exception. JSON schema can define more things about data than a protobuf schema can (e.g. you can define constraints on the valid values of data in a JSON schema, something you cannot do in a Protobuf schema). However, if you’re converting from a Protobuf schema to a JSON schema, such constraints will be absent anyway. If you want a JSON schema in order to be able to express constraints (something Protobuf cannot do), you’ll have to hand-edit the JSON schema anyway to put them in; in which case, manual translation of the schema is probably not that great an extra burden.

    I’m exploring this aspect of my lack of understanding of your needs just in case I’m covering something you have not yet realised about what Protobufs can do for you out of the box. Or, possibly, we end up exploring more complex needs that are hinted at by your question 🙂

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search