Protocol Buffers

Личный сайт Go-разработчика из Казани

Protocol buffers are Google’s language-neutral, platform-neutral, extensible mechanism for serializing structured data – think XML, but smaller, faster, and simpler. You define how you want your data to be structured once, then you can use special generated source code to easily write and read your structured data to and from a variety of data streams and using a variety of languages. Protocol Buffers are Schema Of Messages. They are language agnostic. They can be converted to binary and converted back to message formats using the code generated by the protoc compiler for various languages.

1/* 2* Language Syntax 3*/ 4 5/* 6* Specifying Syntax Of Protocol Buffer Version 7* Specifying Which Protocol Buffer Version To Use 8* It can be usually proto3 or proto2 9*/ 10syntax = "proto3"; 11 12/* 13* Declaring Message In Protocol Buffer: 14* As you can see, each field in the message definition has a unique number. 15* These field numbers are used to identify your fields in the message binary format, 16* and should not be changed once your message type is in use. 17* Note that field numbers in the range 1 through 15 take one byte to encode, including the field number and the field's type (you can find out more about this in Protocol Buffer Encoding). 18* Field numbers in the range 16 through 2047 take two bytes. So you should reserve the numbers 1 through 15 for very frequently occurring message elements. 19* Remember to leave some room for frequently occurring elements that might be added in the future. 20* The smallest field number you can specify is 1, and the largest is 2^29 - 1, or 536,870,911. 21* You also cannot use the numbers 19000 through 19999 (FieldDescriptor::kFirstReservedNumber through FieldDescriptor::kLastReservedNumber), 22* as they are reserved for the Protocol Buffers implementation - the protocol buffer compiler will complain if you use one of these reserved numbers in your .proto. 23* Similarly, you cannot use any previously reserved field numbers. 24* 25*/ 26 27/* 28Syntax For Declaring Message: 29 message ${MessageName} { 30 ${Scalar Value Type} ${FieldName1} = ${Tag Number1}; 31 . 32 . 33 . 34 ${Scalar Value Type} ${FieldNameN} = ${Tag NumberN}; 35 } 36 37Default Values Will be applied any case if the message doesn't contain a existing field defined 38in the message definition 39*/ 40 41message MessageTypes { 42 /* 43 * Scalar Value Types 44 */ 45 string stringType = 1; // A string must always contain UTF-8 encoded or 7-bit ASCII text. Default value = "" 46 47 // Number Types, Default Value = 0 48 int32 int32Type = 2; // Uses Variable Length Encoding. Inefficient For Negative Numbers, Instead Use sint32. 49 int64 int64Type = 3; // Uses Variable Length Encoding. Inefficient For Negative Numbers, Instead Use sint64. 50 uint32 uInt32Type = 4; // Uses Variable Length Encoding 51 uint64 uInt64Type = 5; // Uses Variable Length Encoding 52 sint32 sInt32Type = 6; // Uses Variable Length Encoding. They are efficient in encoding for negative numbers. 53 // Use this instead of int32 for negative numbers 54 sint64 sInt64Type = 7; // Uses Variable Length Encoding. They are efficient in encoding for negative numbers. 55 // Use this instead of int64 for negative numbers. 56 57 fixed32 fixed32Type = 8; // Always four bytes. More efficient than uint32 if values are often greater than 2^28. 58 fixed64 fixed64Type = 9; // Always eight bytes. More efficient than uint64 if values are often greater than 2^56 59 60 sfixed32 sfixed32Type = 10; // Always four bytes. 61 sfixed64 sfixed64Type = 11; // Always Eight bytes. 62 63 bool boolType = 12; // Boolean Type. Default Value = false 64 65 bytes bytesType = 13; // May contain any arbitrary sequence of bytes. Default Value = Empty Bytes 66 67 double doubleType = 14; 68 float floatType = 15; 69 70 enum Week { 71 UNDEFINED = 0; // Tag 0 is always used as default in case of enum 72 SUNDAY = 1; 73 MONDAY = 2; 74 TUESDAY = 3; 75 WEDNESDAY = 4; 76 THURSDAY = 5; 77 FRIDAY = 6; 78 SATURDAY = 7; 79 } 80 Week wkDayType = 16; 81 82 /* 83 * Defining Collection Of Scalar Value Type 84 * Syntax: repeated ${ScalarType} ${name} = TagValue 85 */ 86 repeated string listOfString = 17; // List[String] 87} 88 89/* 90* Defining Defined Message Types In Other Message Definition 91*/ 92message Person { 93 string fname = 1; 94 string sname = 2; 95} 96 97message City { 98 Person p = 1; 99} 100 101/* 102* Nested Message Definitions 103*/ 104 105message NestedMessages { 106 message FirstLevelNestedMessage { 107 string firstString = 1; 108 message SecondLevelNestedMessage { 109 string secondString = 2; 110 } 111 } 112 FirstLevelNestedMessage msg = 1; 113 FirstLevelNestedMessage.SecondLevelNestedMessage msg2 = 2; 114} 115 116/* 117* Importing Message From A File 118*/ 119 120// one.proto 121// message One { 122// string oneMsg = 1; 123// } 124 125// two.proto 126// import "myproject/one.proto" 127// message Two { 128// string twoMsg = 2; 129// } 130 131 132/* 133* Advanced Topics 134*/ 135 136/* 137* Handling Message Type Changes: 138* Never Change/Use The TagNumber Of A Message Field Which Was Removed 139* We should use reserved in case of message definition update. 140* (https://developers.google.com/protocol-buffers/docs/proto3#updating) 141*/ 142 143/* 144* Reserved Fields 145* It's used in case if we need to add/remove new fields into message. 146* Using Reserved Backward and Forward Compatibility Of Messages can be achieved 147*/ 148 149 150message ReservedMessage { 151 reserved 0, 1, 2, 3 to 10; // Set Of Tag Numbers Which Can't be reused. 152 reserved "firstMsg", "secondMsg", "thirdMsg"; // Set Of Labels Which Can't Be reused. 153} 154 155/* 156* Any 157* The Any message type lets you use messages as embedded types without having their .proto definition. 158* An Any contains an arbitrary serialized message as bytes, 159* along with a URL that acts as a globally unique identifier for and resolves to that message's type. 160* For Any to work we need to import it as shown below. 161*/ 162/* 163 import "google/protobuf/any.proto"; 164 message AnySampleMessage { 165 repeated google.protobuf.Any.details = 1; 166 } 167 168*/ 169 170 171/* 172* OneOf 173* There are cases, wherein only one field at-most might be present as part of the message. 174* Note: OneOf messages can't be repeated. 175*/ 176 177message OneOfMessage { 178 oneof msg { 179 string fname = 1; 180 string sname = 2; 181 }; 182} 183 184/* 185* Maps 186* Map fields cannot be repeated. 187* Ordering Of A Map Is Not Guaranteed. 188*/ 189 190message MessageWithMaps { 191 map<string, string> mapOfMessages = 1; 192} 193 194 195/* 196* Packages 197* Used for preventing name clashes between protocol message types 198* Syntax: 199 package ${packageName}; 200 201 To Access the package; 202 ${packageName}.${messageName} = ${tagNumber}; 203*/ 204 205/* 206* Services 207* Message Types Defined For Using In RPC system. 208* When protoc compiler generates for various languages it generates stub methods for the services. 209*/ 210 211message SearchRequest { 212 string queryString = 1; 213} 214 215message SearchResponse { 216 string queryResponse = 1; 217} 218service SearchService { 219 rpc Search (SearchRequest) returns (SearchResponse); 220}

Generating Classes In Various Languages For Protocol Buffers

1protoc --proto_path=IMPORT_PATH --cpp_out=DST_DIR --java_out=DST_DIR --python_out=DST_DIR --go_out=DST_DIR --ruby_out=DST_DIR --objc_out=DST_DIR --csharp_out=DST_DIR path/to/file.proto

References

Google Protocol Buffers