Преобразование json в динамически созданный protobuf в Java

Учитывая следующий ответ json:

{
    "id" : "123456",
    "name" : "John Doe",
    "email" : "[email protected]"
}

И следующий файл user.proto:

message User {
    string id = 1;
    string name = 2;
    string email = 3;
}

Я хотел бы иметь возможность динамически создавать класс сообщений protobuf (компилировать.proto во время выполнения), так что если json-ответ будет усилен полем "phone": "+1234567890" Я мог бы просто загрузить новую версию файла protobuf, чтобы содержать string phone = 4 и получить это поле, выставленное в ответ protobuf, без перезапуска службы.

Если бы я должен был вытащить эти классы из шляпы, я бы хотел написать что-то по следующему коду.

import com.googlecode.protobuf.format.JsonFormat;
import com.googlecode.protobuf.Message;
import org.apache.commons.io.FileUtils;

...

public Message convertToProto(InputStream jsonInputStream){
    // get the latest user.proto file
    String userProtoFile = FileUtils.readFileToString("user.proto");

    Message userProtoMessage = com.acme.ProtobufUtils.compile(userProtoFile);
    Message.Builder builder = userProtoMessage.newBuilderForType(); 
    new JsonFormat().merge(inputStream, Charset.forName("UTF-8"), builder);
    return builder.build();
}

Есть ли существующий метод com.acme.ProtobufUtils.compile(...)? Или как его реализовать? Запуск класса protoc + load кажется излишним, но я готов использовать его, если нет другого варианта...

Ответ 1

Вы не можете скомпилировать файл .proto (по крайней мере, не на Java), однако вы можете предварительно скомпилировать .proto в дескриптор .desc

protoc --descriptor_set_out=user.desc user.proto

а затем используйте синтаксический анализатор DynamicMessage:

DynamicMessage.parseFrom(Descriptors.Descriptor type, byte[] data)

Источник: поток групп google