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