General

Google Protocol Buffer - 주요 상세 내용

구티맨 2022. 8. 9. 16:10

목차

     

    이전 포스팅​

    Google Protocol Buffer

     

    이 포스팅에서는 Protocol Buffer 를 사용하면서, 상세하게 알아두면 좋을 만한 내용을 정리해두었습니다.

    ( 글은 Java를 기준으로 작성 되었습니다. )

    필드 숫자 할당

    // .proto file
    
    message Person {
      optional string name = 1;
      optional int32 id = 2;
      optional string email = 3;
    }
    // project code using PB Code
    
    Person john = Person.newBuilder()
        .setId(1234)
        .setName("John Doe")
        .setEmail("jdoe@example.com")
        .build();
    output = new FileOutputStream(args[0]);
    john.writeTo(output);

    proto 파일을 보면,  Person 이라는 메시지에( 구조화 된 데이터 ) name, id, email이라는 필드를 가지고 있고, 각 필드에는 숫자가 정의 되어 있습니다. 

    enum Foo {
      reserved 2, 15, 9 to 11, 40 to max;
      reserved "FOO", "BAR";
    }

    이 숫자는 필드의 unique number 로써, 바이너리 메시지 포맷에서 필드를 구별하는데 사용되기 때문에 반듯이 unique 해야 합니다.( 필드 삭제 시, 필드 숫자가 실수로 재사용되지 않도록 reserve 해두어야 합니다. )

    숫자는 1 에서 2의 29승 -1( 536,870,911 ) 범위를 사용할 수 있으며, 19000 ~ 19999는 Protocol Buffer에서 사용하고 있으므로 사용할 수 없습니다.

    필드 숫자를 인코딩 할 때, 1 ~ 15 는 한 바이트를 사용하고, 16 ~ 2047은 두 바이트를 사용하므로 1 ~ 15는 자주 사용하는 필드를 위해 남겨두는 것이 좋습니다.

     

    Enum

    enum을 정의할 때는 첫 번째 항목이 항상 0으로 저장되어야 합니다.( proto2와의 호환성과 numeric default value로 사용하기 위해 )

    그리고 compiler가 .proto를 사용해 enum을 생성할 때는 대상이 되는 언어에 dependent 하게 생성이 됩니다.

    그러므로 대상이 되는 언어에 따라 unknown enum value값이 왔을 때 동작이 다릅니다.

    JAVA의 경우, UNRECOGNIZED value가 사용되고, 컴파일 된 PB 코드를 보면 UNRECOGNIZED(-1)이 정의 되어있는 것을 확인할 수 있습니다.

    enum ProductType {
        GUARANTEED = 0;
        PERFORMANCE = 1;
        PREMIUM = 2;
        UNITED = 3;
    }
    
    enum Platform {
        APP = 0;
        WEB = 1;
    }
    public enum Platform
          implements com.google.protobuf.ProtocolMessageEnum {
        APP(0),
        WEB(1),
        UNRECOGNIZED(-1),
        ;
        ...
    }
    
    public enum ProductType
          implements com.google.protobuf.ProtocolMessageEnum {
        GUARANTEED(0),
        PERFORMANCE(1),
        PREMIUM(2),
        UNITED(3),
        UNRECOGNIZED(-1),
        ;
        ...
    }

     

    기타 기억할 Rule

    • 필드 추가 후, 예전 버전 메시지를 새롭게 생성된 코드로 파싱하는 경우, 새롭게 추가 된 필드는( 예전 메시지에 없는 값 ) default value를 저장해 줍니다.
      새롭게 생성된 코드에서 생성한 메시지를 예전 버전 코드에서 파싱하는 경우, 새롭게 추가된 필드를 무시하므로 기존 값들은 문제 없이 파싱이 됩니다.
    • 여러 데이터 타입이 서로 호환이 가능한데, 자세한 내용은 원문을 참조바랍니다.