├── .gitignore ├── .travis.yml ├── CHANGES.md ├── LICENSE ├── README.md ├── dune-project ├── misc ├── README.md ├── messages.proto └── messages_unnested.proto ├── pb-plugin.opam ├── src ├── dune ├── pb_plugin.ml ├── protobuf_reified.ml └── protoc_messages.ml └── test ├── .gitignore ├── __init__.py ├── comprehensive.proto ├── dune ├── test.ml ├── test_gen.py └── test_read.py /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | _build/ 3 | *.native 4 | *.install 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | dist: trusty 3 | before_install: 4 | - sudo apt-get -qq update 5 | - sudo apt-get install -y protobuf-compiler 6 | - sudo pip install protobuf 7 | install: 8 | - wget https://raw.githubusercontent.com/ocaml/ocaml-ci-scripts/master/.travis-opam.sh 9 | env: 10 | - OCAML_VERSION=4.03 11 | - OCAML_VERSION=4.04 12 | - OCAML_VERSION=4.05 13 | script: 14 | - bash -ex .travis-opam.sh 15 | -------------------------------------------------------------------------------- /CHANGES.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yallop/ocaml-pb-plugin/696a9570cc6daf63c5f25780dfa108385a6a43b1/CHANGES.md -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 Jeremy Yallop 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## [Note: this plugin is now developed alongside the library in the [pb](https://github.com/yallop/ocaml-pb) repository.] 2 | 3 | ## pb-plugin 4 | 5 | A [`protoc`][protoc] plugin that turns `.proto` files into OCaml protobuf serialization functions built with the [`pb`][pb] library. 6 | 7 | ### Use 8 | 9 | ``` 10 | protoc --plugin=protoc-gen-custom=$(type -p pb_plugin) --custom_out=./build file.proto 11 | ``` 12 | 13 | ### Implementation notes 14 | 15 | The interface between `protoc` and plugins is defined as a [set of protobuf messages][plugin-messages] that describe the contents of a `.proto` file. 16 | 17 | The `pb-plugin` plugin is bootstrapped. The file [`src/protoc_messages.ml`](src/protoc_messages.ml) that reads and writes messages passed between `protoc` and the `plugin` is generated from the file [`misc/messages_unnested.proto`](misc/messages_unnested.proto) using `pb-plugin` itself 18 | 19 | *** 20 | 21 | [![Travis build Status](https://travis-ci.org/yallop/ocaml-pb-plugin.svg?branch=master)](https://travis-ci.org/yallop/ocaml-pb-plugin) 22 | 23 | [protoc]: https://developers.google.com/protocol-buffers/docs/proto#generating 24 | [pb]: http://github.com/yallop/ocaml-pb 25 | [plugin-messages]: misc/messages.proto 26 | -------------------------------------------------------------------------------- /dune-project: -------------------------------------------------------------------------------- 1 | (lang dune 1.11) 2 | (name pb-plugin) 3 | 4 | (generate_opam_files true) 5 | 6 | (implicit_transitive_deps false) 7 | 8 | (license MIT) 9 | 10 | (maintainers 11 | "Jeremy Yallop " 12 | "Rudi Grinberg ") 13 | (authors "Jeremy Yallop ") 14 | (source (github yallop/ocaml-pb-plugin)) 15 | 16 | (package 17 | (name pb-plugin) 18 | (depends 19 | ocaml 20 | pb 21 | (dune (>= 1.11)) 22 | integers 23 | batteries 24 | result 25 | (angstrom (>= 0.10.0)) 26 | faraday 27 | (ounit (and :with-test (>= 2.0)))) 28 | (synopsis "Plugin for generating pb protobuf message descriptions") 29 | (description "Plugin for generating pb protobuf message descriptions")) 30 | -------------------------------------------------------------------------------- /misc/README.md: -------------------------------------------------------------------------------- 1 | Various `.proto` files: 2 | 3 | * [`messages.proto`](messages.proto): 4 | The protobuf messages that define the interface between the `protoc` 5 | compiler and plugins. 6 | 7 | * [`messages_unnested.proto`](messages_unnested.proto): 8 | An variant of `messages.proto` without nested messages, which are 9 | not currently supported by this plugin. 10 | -------------------------------------------------------------------------------- /misc/messages.proto: -------------------------------------------------------------------------------- 1 | // Protocol Buffers - Google's data interchange format 2 | // Copyright 2008 Google Inc. All rights reserved. 3 | // https://developers.google.com/protocol-buffers/ 4 | // 5 | // Redistribution and use in source and binary forms, with or without 6 | // modification, are permitted provided that the following conditions are 7 | // met: 8 | // 9 | // * Redistributions of source code must retain the above copyright 10 | // notice, this list of conditions and the following disclaimer. 11 | // * Redistributions in binary form must reproduce the above 12 | // copyright notice, this list of conditions and the following disclaimer 13 | // in the documentation and/or other materials provided with the 14 | // distribution. 15 | // * Neither the name of Google Inc. nor the names of its 16 | // contributors may be used to endorse or promote products derived from 17 | // this software without specific prior written permission. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | // Author: kenton@google.com (Kenton Varda) 32 | // Based on original Protocol Buffers design by 33 | // Sanjay Ghemawat, Jeff Dean, and others. 34 | // 35 | // The messages in this file describe the definitions found in .proto files. 36 | // A valid .proto file can be translated directly to a FileDescriptorProto 37 | // without any other information (e.g. without reading its imports). 38 | 39 | 40 | syntax = "proto2"; 41 | 42 | package google.protobuf; 43 | option go_package = "descriptor"; 44 | option java_package = "com.google.protobuf"; 45 | option java_outer_classname = "DescriptorProtos"; 46 | option csharp_namespace = "Google.Protobuf.Reflection"; 47 | option objc_class_prefix = "GPB"; 48 | 49 | // descriptor.proto must be optimized for speed because reflection-based 50 | // algorithms don't work during bootstrapping. 51 | option optimize_for = SPEED; 52 | 53 | // The protocol compiler can output a FileDescriptorSet containing the .proto 54 | // files it parses. 55 | message FileDescriptorSet { 56 | repeated FileDescriptorProto file = 1; 57 | } 58 | 59 | // Describes a complete .proto file. 60 | message FileDescriptorProto { 61 | optional string name = 1; // file name, relative to root of source tree 62 | optional string package = 2; // e.g. "foo", "foo.bar", etc. 63 | 64 | // Names of files imported by this file. 65 | repeated string dependency = 3; 66 | // Indexes of the public imported files in the dependency list above. 67 | repeated int32 public_dependency = 10; 68 | // Indexes of the weak imported files in the dependency list. 69 | // For Google-internal migration only. Do not use. 70 | repeated int32 weak_dependency = 11; 71 | 72 | // All top-level definitions in this file. 73 | repeated DescriptorProto message_type = 4; 74 | repeated EnumDescriptorProto enum_type = 5; 75 | repeated ServiceDescriptorProto service = 6; 76 | repeated FieldDescriptorProto extension = 7; 77 | 78 | optional FileOptions options = 8; 79 | 80 | // This field contains optional information about the original source code. 81 | // You may safely remove this entire field without harming runtime 82 | // functionality of the descriptors -- the information is needed only by 83 | // development tools. 84 | optional SourceCodeInfo source_code_info = 9; 85 | 86 | // The syntax of the proto file. 87 | // The supported values are "proto2" and "proto3". 88 | optional string syntax = 12; 89 | } 90 | 91 | // Describes a message type. 92 | message DescriptorProto { 93 | optional string name = 1; 94 | 95 | repeated FieldDescriptorProto field = 2; 96 | repeated FieldDescriptorProto extension = 6; 97 | 98 | repeated DescriptorProto nested_type = 3; 99 | repeated EnumDescriptorProto enum_type = 4; 100 | 101 | message ExtensionRange { 102 | optional int32 start = 1; 103 | optional int32 end = 2; 104 | } 105 | repeated ExtensionRange extension_range = 5; 106 | 107 | repeated OneofDescriptorProto oneof_decl = 8; 108 | 109 | optional MessageOptions options = 7; 110 | 111 | // Range of reserved tag numbers. Reserved tag numbers may not be used by 112 | // fields or extension ranges in the same message. Reserved ranges may 113 | // not overlap. 114 | message ReservedRange { 115 | optional int32 start = 1; // Inclusive. 116 | optional int32 end = 2; // Exclusive. 117 | } 118 | repeated ReservedRange reserved_range = 9; 119 | // Reserved field names, which may not be used by fields in the same message. 120 | // A given name may only be reserved once. 121 | repeated string reserved_name = 10; 122 | } 123 | 124 | // Describes a field within a message. 125 | message FieldDescriptorProto { 126 | enum Type { 127 | // 0 is reserved for errors. 128 | // Order is weird for historical reasons. 129 | TYPE_DOUBLE = 1; 130 | TYPE_FLOAT = 2; 131 | // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if 132 | // negative values are likely. 133 | TYPE_INT64 = 3; 134 | TYPE_UINT64 = 4; 135 | // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if 136 | // negative values are likely. 137 | TYPE_INT32 = 5; 138 | TYPE_FIXED64 = 6; 139 | TYPE_FIXED32 = 7; 140 | TYPE_BOOL = 8; 141 | TYPE_STRING = 9; 142 | TYPE_GROUP = 10; // Tag-delimited aggregate. 143 | TYPE_MESSAGE = 11; // Length-delimited aggregate. 144 | 145 | // New in version 2. 146 | TYPE_BYTES = 12; 147 | TYPE_UINT32 = 13; 148 | TYPE_ENUM = 14; 149 | TYPE_SFIXED32 = 15; 150 | TYPE_SFIXED64 = 16; 151 | TYPE_SINT32 = 17; // Uses ZigZag encoding. 152 | TYPE_SINT64 = 18; // Uses ZigZag encoding. 153 | }; 154 | 155 | enum Label { 156 | // 0 is reserved for errors 157 | LABEL_OPTIONAL = 1; 158 | LABEL_REQUIRED = 2; 159 | LABEL_REPEATED = 3; 160 | }; 161 | 162 | optional string name = 1; 163 | optional int32 number = 3; 164 | optional Label label = 4; 165 | 166 | // If type_name is set, this need not be set. If both this and type_name 167 | // are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP. 168 | optional Type type = 5; 169 | 170 | // For message and enum types, this is the name of the type. If the name 171 | // starts with a '.', it is fully-qualified. Otherwise, C++-like scoping 172 | // rules are used to find the type (i.e. first the nested types within this 173 | // message are searched, then within the parent, on up to the root 174 | // namespace). 175 | optional string type_name = 6; 176 | 177 | // For extensions, this is the name of the type being extended. It is 178 | // resolved in the same manner as type_name. 179 | optional string extendee = 2; 180 | 181 | // For numeric types, contains the original text representation of the value. 182 | // For booleans, "true" or "false". 183 | // For strings, contains the default text contents (not escaped in any way). 184 | // For bytes, contains the C escaped value. All bytes >= 128 are escaped. 185 | // TODO(kenton): Base-64 encode? 186 | optional string default_value = 7; 187 | 188 | // If set, gives the index of a oneof in the containing type's oneof_decl 189 | // list. This field is a member of that oneof. 190 | optional int32 oneof_index = 9; 191 | 192 | // JSON name of this field. The value is set by protocol compiler. If the 193 | // user has set a "json_name" option on this field, that option's value 194 | // will be used. Otherwise, it's deduced from the field's name by converting 195 | // it to camelCase. 196 | optional string json_name = 10; 197 | 198 | optional FieldOptions options = 8; 199 | } 200 | 201 | // Describes a oneof. 202 | message OneofDescriptorProto { 203 | optional string name = 1; 204 | optional OneofOptions options = 2; 205 | } 206 | 207 | // Describes an enum type. 208 | message EnumDescriptorProto { 209 | optional string name = 1; 210 | 211 | repeated EnumValueDescriptorProto value = 2; 212 | 213 | optional EnumOptions options = 3; 214 | } 215 | 216 | // Describes a value within an enum. 217 | message EnumValueDescriptorProto { 218 | optional string name = 1; 219 | optional int32 number = 2; 220 | 221 | optional EnumValueOptions options = 3; 222 | } 223 | 224 | // Describes a service. 225 | message ServiceDescriptorProto { 226 | optional string name = 1; 227 | repeated MethodDescriptorProto method = 2; 228 | 229 | optional ServiceOptions options = 3; 230 | } 231 | 232 | // Describes a method of a service. 233 | message MethodDescriptorProto { 234 | optional string name = 1; 235 | 236 | // Input and output type names. These are resolved in the same way as 237 | // FieldDescriptorProto.type_name, but must refer to a message type. 238 | optional string input_type = 2; 239 | optional string output_type = 3; 240 | 241 | optional MethodOptions options = 4; 242 | 243 | // Identifies if client streams multiple client messages 244 | optional bool client_streaming = 5 [default=false]; 245 | // Identifies if server streams multiple server messages 246 | optional bool server_streaming = 6 [default=false]; 247 | } 248 | 249 | 250 | // =================================================================== 251 | // Options 252 | 253 | // Each of the definitions above may have "options" attached. These are 254 | // just annotations which may cause code to be generated slightly differently 255 | // or may contain hints for code that manipulates protocol messages. 256 | // 257 | // Clients may define custom options as extensions of the *Options messages. 258 | // These extensions may not yet be known at parsing time, so the parser cannot 259 | // store the values in them. Instead it stores them in a field in the *Options 260 | // message called uninterpreted_option. This field must have the same name 261 | // across all *Options messages. We then use this field to populate the 262 | // extensions when we build a descriptor, at which point all protos have been 263 | // parsed and so all extensions are known. 264 | // 265 | // Extension numbers for custom options may be chosen as follows: 266 | // * For options which will only be used within a single application or 267 | // organization, or for experimental options, use field numbers 50000 268 | // through 99999. It is up to you to ensure that you do not use the 269 | // same number for multiple options. 270 | // * For options which will be published and used publicly by multiple 271 | // independent entities, e-mail protobuf-global-extension-registry@google.com 272 | // to reserve extension numbers. Simply provide your project name (e.g. 273 | // Objective-C plugin) and your project website (if available) -- there's no 274 | // need to explain how you intend to use them. Usually you only need one 275 | // extension number. You can declare multiple options with only one extension 276 | // number by putting them in a sub-message. See the Custom Options section of 277 | // the docs for examples: 278 | // https://developers.google.com/protocol-buffers/docs/proto#options 279 | // If this turns out to be popular, a web service will be set up 280 | // to automatically assign option numbers. 281 | 282 | 283 | message FileOptions { 284 | 285 | // Sets the Java package where classes generated from this .proto will be 286 | // placed. By default, the proto package is used, but this is often 287 | // inappropriate because proto packages do not normally start with backwards 288 | // domain names. 289 | optional string java_package = 1; 290 | 291 | 292 | // If set, all the classes from the .proto file are wrapped in a single 293 | // outer class with the given name. This applies to both Proto1 294 | // (equivalent to the old "--one_java_file" option) and Proto2 (where 295 | // a .proto always translates to a single class, but you may want to 296 | // explicitly choose the class name). 297 | optional string java_outer_classname = 8; 298 | 299 | // If set true, then the Java code generator will generate a separate .java 300 | // file for each top-level message, enum, and service defined in the .proto 301 | // file. Thus, these types will *not* be nested inside the outer class 302 | // named by java_outer_classname. However, the outer class will still be 303 | // generated to contain the file's getDescriptor() method as well as any 304 | // top-level extensions defined in the file. 305 | optional bool java_multiple_files = 10 [default=false]; 306 | 307 | // This option does nothing. 308 | optional bool java_generate_equals_and_hash = 20 [deprecated=true]; 309 | 310 | // If set true, then the Java2 code generator will generate code that 311 | // throws an exception whenever an attempt is made to assign a non-UTF-8 312 | // byte sequence to a string field. 313 | // Message reflection will do the same. 314 | // However, an extension field still accepts non-UTF-8 byte sequences. 315 | // This option has no effect on when used with the lite runtime. 316 | optional bool java_string_check_utf8 = 27 [default=false]; 317 | 318 | 319 | // Generated classes can be optimized for speed or code size. 320 | enum OptimizeMode { 321 | SPEED = 1; // Generate complete code for parsing, serialization, 322 | // etc. 323 | CODE_SIZE = 2; // Use ReflectionOps to implement these methods. 324 | LITE_RUNTIME = 3; // Generate code using MessageLite and the lite runtime. 325 | } 326 | optional OptimizeMode optimize_for = 9 [default=SPEED]; 327 | 328 | // Sets the Go package where structs generated from this .proto will be 329 | // placed. If omitted, the Go package will be derived from the following: 330 | // - The basename of the package import path, if provided. 331 | // - Otherwise, the package statement in the .proto file, if present. 332 | // - Otherwise, the basename of the .proto file, without extension. 333 | optional string go_package = 11; 334 | 335 | 336 | 337 | // Should generic services be generated in each language? "Generic" services 338 | // are not specific to any particular RPC system. They are generated by the 339 | // main code generators in each language (without additional plugins). 340 | // Generic services were the only kind of service generation supported by 341 | // early versions of google.protobuf. 342 | // 343 | // Generic services are now considered deprecated in favor of using plugins 344 | // that generate code specific to your particular RPC system. Therefore, 345 | // these default to false. Old code which depends on generic services should 346 | // explicitly set them to true. 347 | optional bool cc_generic_services = 16 [default=false]; 348 | optional bool java_generic_services = 17 [default=false]; 349 | optional bool py_generic_services = 18 [default=false]; 350 | 351 | // Is this file deprecated? 352 | // Depending on the target platform, this can emit Deprecated annotations 353 | // for everything in the file, or it will be completely ignored; in the very 354 | // least, this is a formalization for deprecating files. 355 | optional bool deprecated = 23 [default=false]; 356 | 357 | // Enables the use of arenas for the proto messages in this file. This applies 358 | // only to generated classes for C++. 359 | optional bool cc_enable_arenas = 31 [default=false]; 360 | 361 | 362 | // Sets the objective c class prefix which is prepended to all objective c 363 | // generated classes from this .proto. There is no default. 364 | optional string objc_class_prefix = 36; 365 | 366 | // Namespace for generated classes; defaults to the package. 367 | optional string csharp_namespace = 37; 368 | 369 | // By default Swift generators will take the proto package and CamelCase it 370 | // replacing '.' with underscore and use that to prefix the types/symbols 371 | // defined. When this options is provided, they will use this value instead 372 | // to prefix the types/symbols defined. 373 | optional string swift_prefix = 39; 374 | 375 | // The parser stores options it doesn't recognize here. See above. 376 | repeated UninterpretedOption uninterpreted_option = 999; 377 | 378 | // Clients can define custom options in extensions of this message. See above. 379 | extensions 1000 to max; 380 | 381 | reserved 38; 382 | } 383 | 384 | message MessageOptions { 385 | // Set true to use the old proto1 MessageSet wire format for extensions. 386 | // This is provided for backwards-compatibility with the MessageSet wire 387 | // format. You should not use this for any other reason: It's less 388 | // efficient, has fewer features, and is more complicated. 389 | // 390 | // The message must be defined exactly as follows: 391 | // message Foo { 392 | // option message_set_wire_format = true; 393 | // extensions 4 to max; 394 | // } 395 | // Note that the message cannot have any defined fields; MessageSets only 396 | // have extensions. 397 | // 398 | // All extensions of your type must be singular messages; e.g. they cannot 399 | // be int32s, enums, or repeated messages. 400 | // 401 | // Because this is an option, the above two restrictions are not enforced by 402 | // the protocol compiler. 403 | optional bool message_set_wire_format = 1 [default=false]; 404 | 405 | // Disables the generation of the standard "descriptor()" accessor, which can 406 | // conflict with a field of the same name. This is meant to make migration 407 | // from proto1 easier; new code should avoid fields named "descriptor". 408 | optional bool no_standard_descriptor_accessor = 2 [default=false]; 409 | 410 | // Is this message deprecated? 411 | // Depending on the target platform, this can emit Deprecated annotations 412 | // for the message, or it will be completely ignored; in the very least, 413 | // this is a formalization for deprecating messages. 414 | optional bool deprecated = 3 [default=false]; 415 | 416 | // Whether the message is an automatically generated map entry type for the 417 | // maps field. 418 | // 419 | // For maps fields: 420 | // map map_field = 1; 421 | // The parsed descriptor looks like: 422 | // message MapFieldEntry { 423 | // option map_entry = true; 424 | // optional KeyType key = 1; 425 | // optional ValueType value = 2; 426 | // } 427 | // repeated MapFieldEntry map_field = 1; 428 | // 429 | // Implementations may choose not to generate the map_entry=true message, but 430 | // use a native map in the target language to hold the keys and values. 431 | // The reflection APIs in such implementions still need to work as 432 | // if the field is a repeated message field. 433 | // 434 | // NOTE: Do not set the option in .proto files. Always use the maps syntax 435 | // instead. The option should only be implicitly set by the proto compiler 436 | // parser. 437 | optional bool map_entry = 7; 438 | 439 | reserved 8; // javalite_serializable 440 | 441 | 442 | // The parser stores options it doesn't recognize here. See above. 443 | repeated UninterpretedOption uninterpreted_option = 999; 444 | 445 | // Clients can define custom options in extensions of this message. See above. 446 | extensions 1000 to max; 447 | } 448 | 449 | message FieldOptions { 450 | // The ctype option instructs the C++ code generator to use a different 451 | // representation of the field than it normally would. See the specific 452 | // options below. This option is not yet implemented in the open source 453 | // release -- sorry, we'll try to include it in a future version! 454 | optional CType ctype = 1 [default = STRING]; 455 | enum CType { 456 | // Default mode. 457 | STRING = 0; 458 | 459 | CORD = 1; 460 | 461 | STRING_PIECE = 2; 462 | } 463 | // The packed option can be enabled for repeated primitive fields to enable 464 | // a more efficient representation on the wire. Rather than repeatedly 465 | // writing the tag and type for each element, the entire array is encoded as 466 | // a single length-delimited blob. In proto3, only explicit setting it to 467 | // false will avoid using packed encoding. 468 | optional bool packed = 2; 469 | 470 | // The jstype option determines the JavaScript type used for values of the 471 | // field. The option is permitted only for 64 bit integral and fixed types 472 | // (int64, uint64, sint64, fixed64, sfixed64). By default these types are 473 | // represented as JavaScript strings. This avoids loss of precision that can 474 | // happen when a large value is converted to a floating point JavaScript 475 | // numbers. Specifying JS_NUMBER for the jstype causes the generated 476 | // JavaScript code to use the JavaScript "number" type instead of strings. 477 | // This option is an enum to permit additional types to be added, 478 | // e.g. goog.math.Integer. 479 | optional JSType jstype = 6 [default = JS_NORMAL]; 480 | enum JSType { 481 | // Use the default type. 482 | JS_NORMAL = 0; 483 | 484 | // Use JavaScript strings. 485 | JS_STRING = 1; 486 | 487 | // Use JavaScript numbers. 488 | JS_NUMBER = 2; 489 | } 490 | 491 | // Should this field be parsed lazily? Lazy applies only to message-type 492 | // fields. It means that when the outer message is initially parsed, the 493 | // inner message's contents will not be parsed but instead stored in encoded 494 | // form. The inner message will actually be parsed when it is first accessed. 495 | // 496 | // This is only a hint. Implementations are free to choose whether to use 497 | // eager or lazy parsing regardless of the value of this option. However, 498 | // setting this option true suggests that the protocol author believes that 499 | // using lazy parsing on this field is worth the additional bookkeeping 500 | // overhead typically needed to implement it. 501 | // 502 | // This option does not affect the public interface of any generated code; 503 | // all method signatures remain the same. Furthermore, thread-safety of the 504 | // interface is not affected by this option; const methods remain safe to 505 | // call from multiple threads concurrently, while non-const methods continue 506 | // to require exclusive access. 507 | // 508 | // 509 | // Note that implementations may choose not to check required fields within 510 | // a lazy sub-message. That is, calling IsInitialized() on the outer message 511 | // may return true even if the inner message has missing required fields. 512 | // This is necessary because otherwise the inner message would have to be 513 | // parsed in order to perform the check, defeating the purpose of lazy 514 | // parsing. An implementation which chooses not to check required fields 515 | // must be consistent about it. That is, for any particular sub-message, the 516 | // implementation must either *always* check its required fields, or *never* 517 | // check its required fields, regardless of whether or not the message has 518 | // been parsed. 519 | optional bool lazy = 5 [default=false]; 520 | 521 | // Is this field deprecated? 522 | // Depending on the target platform, this can emit Deprecated annotations 523 | // for accessors, or it will be completely ignored; in the very least, this 524 | // is a formalization for deprecating fields. 525 | optional bool deprecated = 3 [default=false]; 526 | 527 | // For Google-internal migration only. Do not use. 528 | optional bool weak = 10 [default=false]; 529 | 530 | 531 | // The parser stores options it doesn't recognize here. See above. 532 | repeated UninterpretedOption uninterpreted_option = 999; 533 | 534 | // Clients can define custom options in extensions of this message. See above. 535 | extensions 1000 to max; 536 | 537 | reserved 4; // removed jtype 538 | } 539 | 540 | message OneofOptions { 541 | // The parser stores options it doesn't recognize here. See above. 542 | repeated UninterpretedOption uninterpreted_option = 999; 543 | 544 | // Clients can define custom options in extensions of this message. See above. 545 | extensions 1000 to max; 546 | } 547 | 548 | message EnumOptions { 549 | 550 | // Set this option to true to allow mapping different tag names to the same 551 | // value. 552 | optional bool allow_alias = 2; 553 | 554 | // Is this enum deprecated? 555 | // Depending on the target platform, this can emit Deprecated annotations 556 | // for the enum, or it will be completely ignored; in the very least, this 557 | // is a formalization for deprecating enums. 558 | optional bool deprecated = 3 [default=false]; 559 | 560 | 561 | // The parser stores options it doesn't recognize here. See above. 562 | repeated UninterpretedOption uninterpreted_option = 999; 563 | 564 | // Clients can define custom options in extensions of this message. See above. 565 | extensions 1000 to max; 566 | } 567 | 568 | message EnumValueOptions { 569 | // Is this enum value deprecated? 570 | // Depending on the target platform, this can emit Deprecated annotations 571 | // for the enum value, or it will be completely ignored; in the very least, 572 | // this is a formalization for deprecating enum values. 573 | optional bool deprecated = 1 [default=false]; 574 | 575 | // The parser stores options it doesn't recognize here. See above. 576 | repeated UninterpretedOption uninterpreted_option = 999; 577 | 578 | // Clients can define custom options in extensions of this message. See above. 579 | extensions 1000 to max; 580 | } 581 | 582 | message ServiceOptions { 583 | 584 | // Note: Field numbers 1 through 32 are reserved for Google's internal RPC 585 | // framework. We apologize for hoarding these numbers to ourselves, but 586 | // we were already using them long before we decided to release Protocol 587 | // Buffers. 588 | 589 | // Is this service deprecated? 590 | // Depending on the target platform, this can emit Deprecated annotations 591 | // for the service, or it will be completely ignored; in the very least, 592 | // this is a formalization for deprecating services. 593 | optional bool deprecated = 33 [default=false]; 594 | 595 | // The parser stores options it doesn't recognize here. See above. 596 | repeated UninterpretedOption uninterpreted_option = 999; 597 | 598 | // Clients can define custom options in extensions of this message. See above. 599 | extensions 1000 to max; 600 | } 601 | 602 | message MethodOptions { 603 | 604 | // Note: Field numbers 1 through 32 are reserved for Google's internal RPC 605 | // framework. We apologize for hoarding these numbers to ourselves, but 606 | // we were already using them long before we decided to release Protocol 607 | // Buffers. 608 | 609 | // Is this method deprecated? 610 | // Depending on the target platform, this can emit Deprecated annotations 611 | // for the method, or it will be completely ignored; in the very least, 612 | // this is a formalization for deprecating methods. 613 | optional bool deprecated = 33 [default=false]; 614 | 615 | // Is this method side-effect-free (or safe in HTTP parlance), or idempotent, 616 | // or neither? HTTP based RPC implementation may choose GET verb for safe 617 | // methods, and PUT verb for idempotent methods instead of the default POST. 618 | enum IdempotencyLevel { 619 | IDEMPOTENCY_UNKNOWN = 0; 620 | NO_SIDE_EFFECTS = 1; // implies idempotent 621 | IDEMPOTENT = 2; // idempotent, but may have side effects 622 | } 623 | optional IdempotencyLevel idempotency_level = 624 | 34 [default=IDEMPOTENCY_UNKNOWN]; 625 | 626 | // The parser stores options it doesn't recognize here. See above. 627 | repeated UninterpretedOption uninterpreted_option = 999; 628 | 629 | // Clients can define custom options in extensions of this message. See above. 630 | extensions 1000 to max; 631 | } 632 | 633 | 634 | // A message representing a option the parser does not recognize. This only 635 | // appears in options protos created by the compiler::Parser class. 636 | // DescriptorPool resolves these when building Descriptor objects. Therefore, 637 | // options protos in descriptor objects (e.g. returned by Descriptor::options(), 638 | // or produced by Descriptor::CopyTo()) will never have UninterpretedOptions 639 | // in them. 640 | message UninterpretedOption { 641 | // The name of the uninterpreted option. Each string represents a segment in 642 | // a dot-separated name. is_extension is true iff a segment represents an 643 | // extension (denoted with parentheses in options specs in .proto files). 644 | // E.g.,{ [[]"foo", false], [[]"bar.baz", true], [[]"qux", false] } represents 645 | // "foo.(bar.baz).qux". 646 | message NamePart { 647 | required string name_part = 1; 648 | required bool is_extension = 2; 649 | } 650 | repeated NamePart name = 2; 651 | 652 | // The value of the uninterpreted option, in whatever type the tokenizer 653 | // identified it as during parsing. Exactly one of these should be set. 654 | optional string identifier_value = 3; 655 | optional uint64 positive_int_value = 4; 656 | optional int64 negative_int_value = 5; 657 | optional double double_value = 6; 658 | optional bytes string_value = 7; 659 | optional string aggregate_value = 8; 660 | } 661 | 662 | // =================================================================== 663 | // Optional source code info 664 | 665 | // Encapsulates information about the original source file from which a 666 | // FileDescriptorProto was generated. 667 | message SourceCodeInfo { 668 | // A Location identifies a piece of source code in a .proto file which 669 | // corresponds to a particular definition. This information is intended 670 | // to be useful to IDEs, code indexers, documentation generators, and similar 671 | // tools. 672 | // 673 | // For example, say we have a file like: 674 | // message Foo { 675 | // optional string foo = 1; 676 | // } 677 | // Let's look at just the field definition: 678 | // optional string foo = 1; 679 | // ^ ^^ ^^ ^ ^^^ 680 | // a bc de f ghi 681 | // We have the following locations: 682 | // span path represents 683 | // [[]a,i) [[] 4, 0, 2, 0 ] The whole field definition. 684 | // [[]a,b) [[] 4, 0, 2, 0, 4 ] The label (optional). 685 | // [[]c,d) [[] 4, 0, 2, 0, 5 ] The type (string). 686 | // [[]e,f) [[] 4, 0, 2, 0, 1 ] The name (foo). 687 | // [[]g,h) [[] 4, 0, 2, 0, 3 ] The number (1). 688 | // 689 | // Notes: 690 | // - A location may refer to a repeated field itself (i.e. not to any 691 | // particular index within it). This is used whenever a set of elements are 692 | // logically enclosed in a single code segment. For example, an entire 693 | // extend block (possibly containing multiple extension definitions) will 694 | // have an outer location whose path refers to the "extensions" repeated 695 | // field without an index. 696 | // - Multiple locations may have the same path. This happens when a single 697 | // logical declaration is spread out across multiple places. The most 698 | // obvious example is the "extend" block again -- there may be multiple 699 | // extend blocks in the same scope, each of which will have the same path. 700 | // - A location's span is not always a subset of its parent's span. For 701 | // example, the "extendee" of an extension declaration appears at the 702 | // beginning of the "extend" block and is shared by all extensions within 703 | // the block. 704 | // - Just because a location's span is a subset of some other location's span 705 | // does not mean that it is a descendent. For example, a "group" defines 706 | // both a type and a field in a single declaration. Thus, the locations 707 | // corresponding to the type and field and their components will overlap. 708 | // - Code which tries to interpret locations should probably be designed to 709 | // ignore those that it doesn't understand, as more types of locations could 710 | // be recorded in the future. 711 | repeated Location location = 1; 712 | message Location { 713 | // Identifies which part of the FileDescriptorProto was defined at this 714 | // location. 715 | // 716 | // Each element is a field number or an index. They form a path from 717 | // the root FileDescriptorProto to the place where the definition. For 718 | // example, this path: 719 | // [[] 4, 3, 2, 7, 1 ] 720 | // refers to: 721 | // file.message_type(3) // 4, 3 722 | // .field(7) // 2, 7 723 | // .name() // 1 724 | // This is because FileDescriptorProto.message_type has field number 4: 725 | // repeated DescriptorProto message_type = 4; 726 | // and DescriptorProto.field has field number 2: 727 | // repeated FieldDescriptorProto field = 2; 728 | // and FieldDescriptorProto.name has field number 1: 729 | // optional string name = 1; 730 | // 731 | // Thus, the above path gives the location of a field name. If we removed 732 | // the last element: 733 | // [[] 4, 3, 2, 7 ] 734 | // this path refers to the whole field declaration (from the beginning 735 | // of the label to the terminating semicolon). 736 | repeated int32 path = 1 [packed=true]; 737 | 738 | // Always has exactly three or four elements: start line, start column, 739 | // end line (optional, otherwise assumed same as start line), end column. 740 | // These are packed into a single field for efficiency. Note that line 741 | // and column numbers are zero-based -- typically you will want to add 742 | // 1 to each before displaying to a user. 743 | repeated int32 span = 2 [packed=true]; 744 | 745 | // If this SourceCodeInfo represents a complete declaration, these are any 746 | // comments appearing before and after the declaration which appear to be 747 | // attached to the declaration. 748 | // 749 | // A series of line comments appearing on consecutive lines, with no other 750 | // tokens appearing on those lines, will be treated as a single comment. 751 | // 752 | // leading_detached_comments will keep paragraphs of comments that appear 753 | // before (but not connected to) the current element. Each paragraph, 754 | // separated by empty lines, will be one comment element in the repeated 755 | // field. 756 | // 757 | // Only the comment content is provided; comment markers (e.g. //) are 758 | // stripped out. For block comments, leading whitespace and an asterisk 759 | // will be stripped from the beginning of each line other than the first. 760 | // Newlines are included in the output. 761 | // 762 | // Examples: 763 | // 764 | // optional int32 foo = 1; // Comment attached to foo. 765 | // // Comment attached to bar. 766 | // optional int32 bar = 2; 767 | // 768 | // optional string baz = 3; 769 | // // Comment attached to baz. 770 | // // Another line attached to baz. 771 | // 772 | // // Comment attached to qux. 773 | // // 774 | // // Another line attached to qux. 775 | // optional double qux = 4; 776 | // 777 | // // Detached comment for corge. This is not leading or trailing comments 778 | // // to qux or corge because there are blank lines separating it from 779 | // // both. 780 | // 781 | // // Detached comment for corge paragraph 2. 782 | // 783 | // optional string corge = 5; 784 | // /* Block comment attached 785 | // * to corge. Leading asterisks 786 | // * will be removed. */ 787 | // /* Block comment attached to 788 | // * grault. */ 789 | // optional int32 grault = 6; 790 | // 791 | // // ignored detached comments. 792 | optional string leading_comments = 3; 793 | optional string trailing_comments = 4; 794 | repeated string leading_detached_comments = 6; 795 | } 796 | } 797 | 798 | // Describes the relationship between generated code and its original source 799 | // file. A GeneratedCodeInfo message is associated with only one generated 800 | // source file, but may contain references to different source .proto files. 801 | message GeneratedCodeInfo { 802 | // An Annotation connects some span of text in generated code to an element 803 | // of its generating .proto file. 804 | repeated Annotation annotation = 1; 805 | message Annotation { 806 | // Identifies the element in the original source .proto file. This field 807 | // is formatted the same as SourceCodeInfo.Location.path. 808 | repeated int32 path = 1 [packed=true]; 809 | 810 | // Identifies the filesystem path to the original source .proto. 811 | optional string source_file = 2; 812 | 813 | // Identifies the starting offset in bytes in the generated code 814 | // that relates to the identified object. 815 | optional int32 begin = 3; 816 | 817 | // Identifies the ending offset in bytes in the generated code that 818 | // relates to the identified offset. The end offset should be one past 819 | // the last relevant byte (so the length of the text = end - begin). 820 | optional int32 end = 4; 821 | } 822 | } 823 | 824 | // Protocol Buffers - Google's data interchange format 825 | // Copyright 2008 Google Inc. All rights reserved. 826 | // https://developers.google.com/protocol-buffers/ 827 | // 828 | // Redistribution and use in source and binary forms, with or without 829 | // modification, are permitted provided that the following conditions are 830 | // met: 831 | // 832 | // * Redistributions of source code must retain the above copyright 833 | // notice, this list of conditions and the following disclaimer. 834 | // * Redistributions in binary form must reproduce the above 835 | // copyright notice, this list of conditions and the following disclaimer 836 | // in the documentation and/or other materials provided with the 837 | // distribution. 838 | // * Neither the name of Google Inc. nor the names of its 839 | // contributors may be used to endorse or promote products derived from 840 | // this software without specific prior written permission. 841 | // 842 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 843 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 844 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 845 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 846 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 847 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 848 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 849 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 850 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 851 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 852 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 853 | 854 | // Author: kenton@google.com (Kenton Varda) 855 | // 856 | // WARNING: The plugin interface is currently EXPERIMENTAL and is subject to 857 | // change. 858 | // 859 | // protoc (aka the Protocol Compiler) can be extended via plugins. A plugin is 860 | // just a program that reads a CodeGeneratorRequest from stdin and writes a 861 | // CodeGeneratorResponse to stdout. 862 | // 863 | // Plugins written using C++ can use google/protobuf/compiler/plugin.h instead 864 | // of dealing with the raw protocol defined here. 865 | // 866 | // A plugin executable needs only to be placed somewhere in the path. The 867 | // plugin should be named "protoc-gen-$NAME", and will then be used when the 868 | // flag "--${NAME}_out" is passed to protoc. 869 | 870 | //syntax = "proto2"; 871 | //package google.protobuf.compiler; 872 | //option java_package = "com.google.protobuf.compiler"; 873 | //option java_outer_classname = "PluginProtos"; 874 | 875 | //option go_package = "plugin_go"; 876 | 877 | //import "google/protobuf/descriptor.proto"; 878 | 879 | // The version number of protocol compiler. 880 | message Version { 881 | optional int32 major = 1; 882 | optional int32 minor = 2; 883 | optional int32 patch = 3; 884 | // A suffix for alpha, beta or rc release, e.g., "alpha-1", "rc2". It should 885 | // be empty for mainline stable releases. 886 | optional string suffix = 4; 887 | } 888 | 889 | // An encoded CodeGeneratorRequest is written to the plugin's stdin. 890 | message CodeGeneratorRequest { 891 | // The .proto files that were explicitly listed on the command-line. The 892 | // code generator should generate code only for these files. Each file's 893 | // descriptor will be included in proto_file, below. 894 | repeated string file_to_generate = 1; 895 | 896 | // The generator parameter passed on the command-line. 897 | optional string parameter = 2; 898 | 899 | // FileDescriptorProtos for all files in files_to_generate and everything 900 | // they import. The files will appear in topological order, so each file 901 | // appears before any file that imports it. 902 | // 903 | // protoc guarantees that all proto_files will be written after 904 | // the fields above, even though this is not technically guaranteed by the 905 | // protobuf wire format. This theoretically could allow a plugin to stream 906 | // in the FileDescriptorProtos and handle them one by one rather than read 907 | // the entire set into memory at once. However, as of this writing, this 908 | // is not similarly optimized on protoc's end -- it will store all fields in 909 | // memory at once before sending them to the plugin. 910 | repeated FileDescriptorProto proto_file = 15; 911 | 912 | // The version number of protocol compiler. 913 | optional Version compiler_version = 3; 914 | } 915 | 916 | // The plugin writes an encoded CodeGeneratorResponse to stdout. 917 | message CodeGeneratorResponse { 918 | // Error message. If non-empty, code generation failed. The plugin process 919 | // should exit with status code zero even if it reports an error in this way. 920 | // 921 | // This should be used to indicate errors in .proto files which prevent the 922 | // code generator from generating correct code. Errors which indicate a 923 | // problem in protoc itself -- such as the input CodeGeneratorRequest being 924 | // unparseable -- should be reported by writing a message to stderr and 925 | // exiting with a non-zero status code. 926 | optional string error = 1; 927 | 928 | // Represents a single generated file. 929 | message File { 930 | // The file name, relative to the output directory. The name must not 931 | // contain "." or ".." components and must be relative, not be absolute (so, 932 | // the file cannot lie outside the output directory). "/" must be used as 933 | // the path separator, not "\". 934 | // 935 | // If the name is omitted, the content will be appended to the previous 936 | // file. This allows the generator to break large files into small chunks, 937 | // and allows the generated text to be streamed back to protoc so that large 938 | // files need not reside completely in memory at one time. Note that as of 939 | // this writing protoc does not optimize for this -- it will read the entire 940 | // CodeGeneratorResponse before writing files to disk. 941 | optional string name = 1; 942 | 943 | // If non-empty, indicates that the named file should already exist, and the 944 | // content here is to be inserted into that file at a defined insertion 945 | // point. This feature allows a code generator to extend the output 946 | // produced by another code generator. The original generator may provide 947 | // insertion points by placing special annotations in the file that look 948 | // like: 949 | // @@protoc_insertion_point(NAME) 950 | // The annotation can have arbitrary text before and after it on the line, 951 | // which allows it to be placed in a comment. NAME should be replaced with 952 | // an identifier naming the point -- this is what other generators will use 953 | // as the insertion_point. Code inserted at this point will be placed 954 | // immediately above the line containing the insertion point (thus multiple 955 | // insertions to the same point will come out in the order they were added). 956 | // The double-@ is intended to make it unlikely that the generated code 957 | // could contain things that look like insertion points by accident. 958 | // 959 | // For example, the C++ code generator places the following line in the 960 | // .pb.h files that it generates: 961 | // // @@protoc_insertion_point(namespace_scope) 962 | // This line appears within the scope of the file's package namespace, but 963 | // outside of any particular class. Another plugin can then specify the 964 | // insertion_point "namespace_scope" to generate additional classes or 965 | // other declarations that should be placed in this scope. 966 | // 967 | // Note that if the line containing the insertion point begins with 968 | // whitespace, the same whitespace will be added to every line of the 969 | // inserted text. This is useful for languages like Python, where 970 | // indentation matters. In these languages, the insertion point comment 971 | // should be indented the same amount as any inserted code will need to be 972 | // in order to work correctly in that context. 973 | // 974 | // The code generator that generates the initial file and the one which 975 | // inserts into it must both run as part of a single invocation of protoc. 976 | // Code generators are executed in the order in which they appear on the 977 | // command line. 978 | // 979 | // If |insertion_point| is present, |name| must also be present. 980 | optional string insertion_point = 2; 981 | 982 | // The file contents. 983 | optional string content = 15; 984 | } 985 | repeated File file = 15; 986 | } 987 | -------------------------------------------------------------------------------- /misc/messages_unnested.proto: -------------------------------------------------------------------------------- 1 | // no nested types 2 | // no extension ranges 3 | // no reserved ranges 4 | 5 | syntax = "proto2"; 6 | 7 | package google.protobuf; 8 | option go_package = "descriptor"; 9 | option java_package = "com.google.protobuf"; 10 | option java_outer_classname = "DescriptorProtos"; 11 | option csharp_namespace = "Google.Protobuf.Reflection"; 12 | option objc_class_prefix = "GPB"; 13 | 14 | option optimize_for = SPEED; 15 | 16 | message FileDescriptorSet { 17 | repeated FileDescriptorProto file = 1; 18 | } 19 | 20 | message FileDescriptorProto { 21 | optional string name = 1; 22 | optional string package = 2; 23 | 24 | repeated string dependency = 3; 25 | 26 | repeated int32 public_dependency = 10; 27 | 28 | repeated int32 weak_dependency = 11; 29 | 30 | repeated DescriptorProto message_type = 4; 31 | repeated EnumDescriptorProto enum_type = 5; 32 | repeated ServiceDescriptorProto service = 6; 33 | repeated FieldDescriptorProto extension = 7; 34 | 35 | optional FileOptions options = 8; 36 | 37 | optional SourceCodeInfo source_code_info = 9; 38 | 39 | optional string syntax = 12; 40 | } 41 | 42 | message ExtensionRange { 43 | optional int32 start = 1; 44 | optional int32 end = 2; 45 | } 46 | 47 | message ReservedRange { 48 | optional int32 start = 1; 49 | optional int32 end = 2; 50 | } 51 | 52 | message DescriptorProto { 53 | optional string name = 1; 54 | 55 | repeated FieldDescriptorProto field = 2; 56 | repeated FieldDescriptorProto extension = 6; 57 | 58 | repeated DescriptorProto nested_type = 3; 59 | repeated EnumDescriptorProto enum_type = 4; 60 | 61 | repeated ExtensionRange extension_range = 5; 62 | 63 | repeated OneofDescriptorProto oneof_decl = 8; 64 | 65 | optional MessageOptions options = 7; 66 | 67 | repeated ReservedRange reserved_range = 9; 68 | 69 | repeated string reserved_name = 10; 70 | } 71 | 72 | enum Label { 73 | 74 | LABEL_OPTIONAL = 1; 75 | LABEL_REQUIRED = 2; 76 | LABEL_REPEATED = 3; 77 | }; 78 | 79 | enum Type { 80 | 81 | TYPE_DOUBLE = 1; 82 | TYPE_FLOAT = 2; 83 | 84 | TYPE_INT64 = 3; 85 | TYPE_UINT64 = 4; 86 | 87 | TYPE_INT32 = 5; 88 | TYPE_FIXED64 = 6; 89 | TYPE_FIXED32 = 7; 90 | TYPE_BOOL = 8; 91 | TYPE_STRING = 9; 92 | TYPE_GROUP = 10; 93 | TYPE_MESSAGE = 11; 94 | 95 | TYPE_BYTES = 12; 96 | TYPE_UINT32 = 13; 97 | TYPE_ENUM = 14; 98 | TYPE_SFIXED32 = 15; 99 | TYPE_SFIXED64 = 16; 100 | TYPE_SINT32 = 17; 101 | TYPE_SINT64 = 18; 102 | }; 103 | 104 | message FieldDescriptorProto { 105 | 106 | 107 | optional string name = 1; 108 | optional int32 number = 3; 109 | optional Label label = 4; 110 | 111 | optional Type type = 5; 112 | 113 | optional string type_name = 6; 114 | 115 | optional string extendee = 2; 116 | 117 | optional string default_value = 7; 118 | 119 | optional int32 oneof_index = 9; 120 | 121 | optional string json_name = 10; 122 | 123 | optional FieldOptions options = 8; 124 | } 125 | 126 | message OneofDescriptorProto { 127 | optional string name = 1; 128 | optional OneofOptions options = 2; 129 | } 130 | 131 | message EnumDescriptorProto { 132 | optional string name = 1; 133 | 134 | repeated EnumValueDescriptorProto value = 2; 135 | 136 | optional EnumOptions options = 3; 137 | } 138 | 139 | message EnumValueDescriptorProto { 140 | optional string name = 1; 141 | optional int32 number = 2; 142 | 143 | optional EnumValueOptions options = 3; 144 | } 145 | 146 | message ServiceDescriptorProto { 147 | optional string name = 1; 148 | repeated MethodDescriptorProto method = 2; 149 | 150 | optional ServiceOptions options = 3; 151 | } 152 | 153 | message MethodDescriptorProto { 154 | optional string name = 1; 155 | 156 | optional string input_type = 2; 157 | optional string output_type = 3; 158 | 159 | optional MethodOptions options = 4; 160 | 161 | optional bool client_streaming = 5 [default=false]; 162 | 163 | optional bool server_streaming = 6 [default=false]; 164 | } 165 | 166 | enum OptimizeMode { 167 | SPEED = 1; 168 | 169 | CODE_SIZE = 2; 170 | LITE_RUNTIME = 3; 171 | } 172 | 173 | message FileOptions { 174 | 175 | optional string java_package = 1; 176 | 177 | optional string java_outer_classname = 8; 178 | 179 | optional bool java_multiple_files = 10 [default=false]; 180 | 181 | optional bool java_generate_equals_and_hash = 20 [deprecated=true]; 182 | 183 | optional bool java_string_check_utf8 = 27 [default=false]; 184 | 185 | optional OptimizeMode optimize_for = 9 [default=SPEED]; 186 | 187 | optional string go_package = 11; 188 | 189 | optional bool cc_generic_services = 16 [default=false]; 190 | optional bool java_generic_services = 17 [default=false]; 191 | optional bool py_generic_services = 18 [default=false]; 192 | 193 | optional bool deprecated = 23 [default=false]; 194 | 195 | optional bool cc_enable_arenas = 31 [default=false]; 196 | 197 | optional string objc_class_prefix = 36; 198 | 199 | optional string csharp_namespace = 37; 200 | 201 | optional string swift_prefix = 39; 202 | 203 | repeated UninterpretedOption uninterpreted_option = 999; 204 | 205 | // extensions 1000 to max; 206 | 207 | // reserved 38; 208 | } 209 | 210 | message MessageOptions { 211 | 212 | optional bool message_set_wire_format = 1 [default=false]; 213 | 214 | optional bool no_standard_descriptor_accessor = 2 [default=false]; 215 | 216 | optional bool deprecated = 3 [default=false]; 217 | 218 | optional bool map_entry = 7; 219 | 220 | // reserved 8; 221 | 222 | repeated UninterpretedOption uninterpreted_option = 999; 223 | 224 | // extensions 1000 to max; 225 | } 226 | 227 | enum CType { 228 | 229 | STRING = 0; 230 | 231 | CORD = 1; 232 | 233 | STRING_PIECE = 2; 234 | } 235 | 236 | enum JSType { 237 | 238 | JS_NORMAL = 0; 239 | 240 | JS_STRING = 1; 241 | 242 | JS_NUMBER = 2; 243 | } 244 | 245 | message FieldOptions { 246 | 247 | optional CType ctype = 1 [default = STRING]; 248 | 249 | optional bool packed = 2; 250 | 251 | optional JSType jstype = 6 [default = JS_NORMAL]; 252 | 253 | optional bool lazy = 5 [default=false]; 254 | 255 | optional bool deprecated = 3 [default=false]; 256 | 257 | optional bool weak = 10 [default=false]; 258 | 259 | repeated UninterpretedOption uninterpreted_option = 999; 260 | 261 | // extensions 1000 to max; 262 | 263 | // reserved 4; 264 | } 265 | 266 | message OneofOptions { 267 | 268 | repeated UninterpretedOption uninterpreted_option = 999; 269 | 270 | // extensions 1000 to max; 271 | } 272 | 273 | message EnumOptions { 274 | 275 | optional bool allow_alias = 2; 276 | 277 | optional bool deprecated = 3 [default=false]; 278 | 279 | repeated UninterpretedOption uninterpreted_option = 999; 280 | 281 | // extensions 1000 to max; 282 | } 283 | 284 | message EnumValueOptions { 285 | 286 | optional bool deprecated = 1 [default=false]; 287 | 288 | repeated UninterpretedOption uninterpreted_option = 999; 289 | 290 | // extensions 1000 to max; 291 | } 292 | 293 | message ServiceOptions { 294 | 295 | optional bool deprecated = 33 [default=false]; 296 | 297 | repeated UninterpretedOption uninterpreted_option = 999; 298 | 299 | // extensions 1000 to max; 300 | } 301 | 302 | enum IdempotencyLevel { 303 | IDEMPOTENCY_UNKNOWN = 0; 304 | NO_SIDE_EFFECTS = 1; 305 | IDEMPOTENT = 2; 306 | } 307 | 308 | message MethodOptions { 309 | 310 | optional bool deprecated = 33 [default=false]; 311 | 312 | optional IdempotencyLevel idempotency_level = 313 | 34 [default=IDEMPOTENCY_UNKNOWN]; 314 | 315 | repeated UninterpretedOption uninterpreted_option = 999; 316 | 317 | // extensions 1000 to max; 318 | } 319 | 320 | message NamePart { 321 | required string name_part = 1; 322 | required bool is_extension = 2; 323 | } 324 | 325 | message UninterpretedOption { 326 | 327 | repeated NamePart name = 2; 328 | 329 | optional string identifier_value = 3; 330 | optional uint64 positive_int_value = 4; 331 | optional int64 negative_int_value = 5; 332 | optional double double_value = 6; 333 | optional bytes string_value = 7; 334 | optional string aggregate_value = 8; 335 | } 336 | 337 | message Location { 338 | 339 | repeated int32 path = 1 [packed=true]; 340 | 341 | repeated int32 span = 2 [packed=true]; 342 | 343 | optional string leading_comments = 3; 344 | optional string trailing_comments = 4; 345 | repeated string leading_detached_comments = 6; 346 | } 347 | 348 | message SourceCodeInfo { 349 | 350 | repeated Location location = 1; 351 | } 352 | 353 | message Annotation { 354 | 355 | repeated int32 path = 1 [packed=true]; 356 | 357 | optional string source_file = 2; 358 | 359 | optional int32 begin = 3; 360 | 361 | optional int32 end = 4; 362 | } 363 | 364 | message GeneratedCodeInfo { 365 | 366 | repeated Annotation annotation = 1; 367 | } 368 | 369 | message Version { 370 | optional int32 major = 1; 371 | optional int32 minor = 2; 372 | optional int32 patch = 3; 373 | 374 | optional string suffix = 4; 375 | } 376 | 377 | message CodeGeneratorRequest { 378 | 379 | repeated string file_to_generate = 1; 380 | 381 | optional string parameter = 2; 382 | 383 | repeated FileDescriptorProto proto_file = 15; 384 | 385 | optional Version compiler_version = 3; 386 | } 387 | 388 | message File { 389 | 390 | optional string name = 1; 391 | 392 | optional string insertion_point = 2; 393 | 394 | optional string content = 15; 395 | } 396 | 397 | message CodeGeneratorResponse { 398 | 399 | optional string error = 1; 400 | 401 | repeated File file = 15; 402 | } 403 | -------------------------------------------------------------------------------- /pb-plugin.opam: -------------------------------------------------------------------------------- 1 | # This file is generated by dune, edit dune-project instead 2 | opam-version: "2.0" 3 | synopsis: "Plugin for generating pb protobuf message descriptions" 4 | description: "Plugin for generating pb protobuf message descriptions" 5 | maintainer: [ 6 | "Jeremy Yallop " "Rudi Grinberg " 7 | ] 8 | authors: ["Jeremy Yallop "] 9 | license: "MIT" 10 | homepage: "https://github.com/yallop/ocaml-pb-plugin" 11 | bug-reports: "https://github.com/yallop/ocaml-pb-plugin/issues" 12 | depends: [ 13 | "ocaml" 14 | "pb" 15 | "dune" {>= "1.11"} 16 | "integers" 17 | "batteries" 18 | "result" 19 | "angstrom" {>= "0.10.0"} 20 | "faraday" 21 | "ounit" {with-test & >= "2.0"} 22 | ] 23 | build: [ 24 | ["dune" "subst"] {pinned} 25 | [ 26 | "dune" 27 | "build" 28 | "-p" 29 | name 30 | "-j" 31 | jobs 32 | "@install" 33 | "@runtest" {with-test} 34 | "@doc" {with-doc} 35 | ] 36 | ] 37 | dev-repo: "git+https://github.com/yallop/ocaml-pb-plugin.git" 38 | -------------------------------------------------------------------------------- /src/dune: -------------------------------------------------------------------------------- 1 | (executable 2 | (libraries pb integers batteries faraday angstrom) 3 | (name pb_plugin) 4 | (public_name pb-plugin)) 5 | -------------------------------------------------------------------------------- /src/pb_plugin.ml: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) 2017 Jeremy Yallop . 3 | * 4 | * This file is distributed under the terms of the MIT License. 5 | * See the file LICENSE for details. 6 | *) 7 | 8 | module M = Protoc_messages 9 | module G = Protobuf_reified.Generate 10 | 11 | (** Error handling *) 12 | exception Error of string 13 | 14 | let failf fmt = Printf.kprintf (fun s -> raise (Error s)) fmt 15 | let warnf fmt = Printf.fprintf stderr ("Warning: " ^^ fmt ^^ "\n") 16 | let is_some = function Some _ -> true | _ -> false 17 | let iter_opt f = function Some x -> f x | None -> () 18 | let map_opt f = function Some x -> Some (f x) | None -> None 19 | 20 | let basename s = 21 | let last = pred (String.length s) in 22 | match String.rindex_from s last '.' with 23 | i -> String.sub s (succ i) (last - i) 24 | | exception Not_found -> s 25 | 26 | module Context : 27 | sig 28 | type t 29 | val create : package:string option -> t 30 | 31 | val enum : t -> string -> G.enum 32 | (** hash-consed enums *) 33 | 34 | val message : t -> string -> G.message 35 | (** hash-consed messages *) 36 | 37 | val write_ml : Format.formatter -> t -> unit 38 | (** write out the contents of the context as an OCaml module *) 39 | end = 40 | struct 41 | type t = { 42 | package: string option; 43 | enums: (string, G.enum) Hashtbl.t; 44 | messages: (string, G.message) Hashtbl.t; 45 | } 46 | let create ~package = 47 | { package; 48 | messages = Hashtbl.create 10; 49 | enums = Hashtbl.create 10 } 50 | 51 | let message {messages; _} s = 52 | let s = basename s in 53 | match Hashtbl.find messages s with 54 | | m -> m 55 | | exception Not_found -> 56 | let m = G.message s in (Hashtbl.add messages s m; m) 57 | 58 | let enum {enums; _} s = 59 | let s = basename s in 60 | match Hashtbl.find enums s with 61 | | e -> e 62 | | exception Not_found -> 63 | let e = G.enum s in (Hashtbl.add enums s e; e) 64 | 65 | let write_ml fmt { package=_ ; enums ; messages } = 66 | (* TODO: package? *) 67 | let as_list h = Hashtbl.fold (fun _ -> List.cons) h [] in 68 | G.write fmt (as_list messages) (as_list enums) 69 | end 70 | 71 | module Enum : 72 | sig 73 | val generate : Context.t -> M.EnumDescriptorProto.s -> unit 74 | end = 75 | struct 76 | module EVO = M.EnumValueOptions 77 | 78 | let handle_option { EVO.deprecated; uninterpreted_option=_ } = 79 | if deprecated 80 | then warnf "ignoring option deprecated"; 81 | 82 | module EV = M.EnumValueDescriptorProto 83 | 84 | let genenum_value e = function 85 | | { EV.name = None; _ } -> failf "nameless enum values are not supported" 86 | | { EV.number = None; _ } -> failf "numberless enum values are not supported" 87 | | { EV.name = Some name; number = Some number; options } -> 88 | iter_opt handle_option options; 89 | G.constant name e number 90 | 91 | module E = M.EnumDescriptorProto 92 | 93 | let handle_option { M.EnumOptions.allow_alias; deprecated; uninterpreted_option=_ } = 94 | begin 95 | if is_some allow_alias 96 | then warnf "ignoring option allow_alias"; 97 | 98 | if deprecated 99 | then warnf "ignoring option deprecated"; 100 | end 101 | 102 | let generate context = function 103 | | { E.name = None; _ } -> failf "nameless enum values are not supported" 104 | | { E.name = Some name; value; options } -> 105 | iter_opt handle_option options; 106 | let e = Context.enum context name in 107 | List.iter (genenum_value e) value 108 | end 109 | 110 | 111 | module Message : 112 | sig 113 | val generate : Context.t -> M.DescriptorProto.s -> unit 114 | end = 115 | struct 116 | let gentype context t name = 117 | match M.Type.T.of_value (Pb.constant_value t), name with 118 | | `TYPE_DOUBLE, _ -> G.double 119 | | `TYPE_FLOAT, _ -> G.float 120 | | `TYPE_INT64, _ -> G.int64 121 | | `TYPE_UINT64, _ -> G.uint64 122 | | `TYPE_INT32, _ -> G.int32 123 | | `TYPE_FIXED64, _ -> G.fixed64 124 | | `TYPE_FIXED32, _ -> G.fixed32 125 | | `TYPE_BOOL, _ -> G.bool 126 | | `TYPE_STRING, _ -> G.string 127 | | `TYPE_GROUP, _ -> failf "groups are not supported" 128 | | `TYPE_MESSAGE, None -> failf "message fields without names are not supported" 129 | | `TYPE_MESSAGE, Some m -> G.message_field (Context.message context m) 130 | | `TYPE_BYTES, _ -> G.bytes 131 | | `TYPE_UINT32, _ -> G.uint32 132 | | `TYPE_ENUM, None -> failf "enum fields without names are not supported" 133 | | `TYPE_ENUM, Some e -> G.enum_field (Context.enum context e) 134 | | `TYPE_SFIXED32, _ -> G.sfixed32 135 | | `TYPE_SFIXED64, _ -> G.sfixed64 136 | | `TYPE_SINT32, _ -> G.sint32 137 | | `TYPE_SINT64, _ -> G.sint64 138 | 139 | module FO = M.FieldOptions 140 | 141 | let handle_option { FO.ctype=_; FO.packed; FO.jstype=_; FO.lazy_; FO.deprecated; FO.weak; 142 | FO.uninterpreted_option=_ } = 143 | begin 144 | if is_some packed 145 | then warnf "ignoring option packed"; 146 | 147 | if is_some packed 148 | then warnf "ignoring option packed"; 149 | 150 | if lazy_ 151 | then warnf "ignoring option lazy"; 152 | 153 | if deprecated 154 | then warnf "ignoring option deprecated"; 155 | 156 | if weak 157 | then warnf "ignoring option weak"; 158 | end 159 | 160 | module F = M.FieldDescriptorProto 161 | 162 | let genfield context msg = function 163 | | { F.name = None; _ } -> failf "nameless message fields not supported" 164 | | { F.number = None; _ } -> failf "numberless message fields not supported" 165 | | { F.type_ = None; _ } -> failf "typeless message fields not supported" 166 | | { F.name = Some name; number = Some number; label; type_ = Some type_; type_name; 167 | extendee; default_value; oneof_index; options; json_name=_ } as _r -> 168 | iter_opt handle_option options; 169 | begin 170 | if is_some extendee 171 | then warnf "ignoring extendee"; 172 | 173 | if is_some oneof_index 174 | then warnf "ignoring oneof_index"; 175 | end; 176 | let labelf = match label with 177 | None -> G.required 178 | | Some l -> match M.Label.T.of_value (Pb.constant_value l) with 179 | | `LABEL_REQUIRED -> G.required 180 | | `LABEL_REPEATED -> G.repeated 181 | | `LABEL_OPTIONAL -> 182 | begin match default_value with 183 | | Some default -> G.optional ~default 184 | | None -> G.optional ?default:None 185 | end 186 | in 187 | let typ = gentype context type_ type_name in 188 | labelf name msg typ number 189 | 190 | module MO = M.MessageOptions 191 | 192 | let handle_options { MO.message_set_wire_format; 193 | no_standard_descriptor_accessor; 194 | deprecated: bool; 195 | map_entry; 196 | uninterpreted_option=_ } = 197 | begin 198 | if message_set_wire_format 199 | then warnf "ignoring option message_set_wire_format"; 200 | 201 | if no_standard_descriptor_accessor 202 | then warnf "ignoring option no_standard_descriptor_accessor"; 203 | 204 | if deprecated 205 | then warnf "ignoring option deprecated"; 206 | 207 | if is_some map_entry 208 | then warnf "ignoring option map_entry"; 209 | end 210 | 211 | module D = M.DescriptorProto 212 | 213 | let generate context = function 214 | | { D.name = None; _ } -> failf "nameless messages not supported" 215 | | { D.name = Some name; field; extension; nested_type; enum_type; 216 | extension_range; oneof_decl; options; reserved_range; reserved_name } -> 217 | begin 218 | List.iter (fun _ -> failf "extension entries unsupported") extension; 219 | List.iter (fun _ -> failf "nested types unsupported") nested_type; 220 | List.iter (fun _ -> failf "nested enums unsupported") enum_type; 221 | List.iter (fun _ -> failf "extension ranges unsupported") extension_range; 222 | List.iter (fun _ -> failf "oneof declarations unsupported") oneof_decl; 223 | List.iter (fun _ -> failf "reserved ranges unsupported") reserved_range; 224 | List.iter (fun _ -> failf "reserved names unsupported") reserved_name; 225 | 226 | iter_opt handle_options options; 227 | 228 | let msg = Context.message context name in 229 | List.iter (genfield context msg) field 230 | end 231 | end 232 | 233 | let generate1 _input_file 234 | { M.FileDescriptorProto.name; enum_type; message_type; service; package; 235 | dependency=_; (* ? *) 236 | public_dependency=_; (* ? *) 237 | weak_dependency=_; (* ? *) 238 | extension=_; (* ? *) 239 | options=_; (* ? *) 240 | source_code_info=_; (* Locations *) 241 | syntax=_ (* protobuf syntax version (e.g. proto3) *) } : 242 | M.File.T.m Pb.msg = 243 | begin 244 | let context = Context.create ~package in 245 | begin match service with [] -> () | _ :: _ -> failf "Services not yet supported" end; 246 | List.iter (Enum.generate context) enum_type; 247 | let () = List.iter (Message.generate context) message_type in 248 | let name = map_opt 249 | (fun c -> Filename.chop_extension c ^ ".ml") name in 250 | M.File.mk ?name 251 | ~content:(Format.asprintf "%a" Context.write_ml context) 252 | () 253 | end 254 | 255 | let generate files proto_files = 256 | match List.combine files proto_files with 257 | | [(file, proto_file)] -> [generate1 file proto_file] 258 | | [] -> failf "error: exactly one filename (not zero) must be specified" 259 | | _::_::_ -> failf "error: exactly one filename (not more) must be specified" 260 | | exception Invalid_argument _ -> 261 | failf "Mismatched lengths: %d files, %d proto_files" 262 | (List.length files) 263 | (List.length proto_files) 264 | 265 | let run msg = 266 | let { M.CodeGeneratorRequest.file_to_generate; 267 | proto_file; parameter=_; compiler_version=_ } = 268 | M.CodeGeneratorRequest.extract msg 269 | in 270 | match generate file_to_generate proto_file with 271 | | files -> 272 | M.CodeGeneratorResponse.mk ~file:files () 273 | | exception (Error s) -> 274 | M.CodeGeneratorResponse.mk ~file:[] ~error:s () 275 | 276 | 277 | let main () = 278 | let stdin_buf = BatIO.(read_all stdin) in 279 | match Angstrom.parse_string (Pb.read M.CodeGeneratorRequest.T.t) stdin_buf with 280 | Result.Error e -> failf "Error parssing request: %s" e 281 | | Result.Ok msg -> print_string (Faraday.serialize_to_string 282 | (Pb.write (run msg))) 283 | 284 | let () = main () 285 | -------------------------------------------------------------------------------- /src/protobuf_reified.ml: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) 2017 Jeremy Yallop . 3 | * 4 | * This file is distributed under the terms of the MIT License. 5 | * See the file LICENSE for details. 6 | *) 7 | 8 | let failf fmt = Printf.kprintf failwith fmt 9 | 10 | module type GEN = 11 | sig 12 | type message 13 | val message : string -> message 14 | 15 | type enum 16 | val enum : string -> enum 17 | val constant : string -> enum -> int32 -> unit 18 | 19 | type field 20 | val enum_field : enum -> field 21 | val message_field : message -> field 22 | val bool : field 23 | val int32 : field 24 | val sint32 : field 25 | val sfixed32 : field 26 | val int64 : field 27 | val sint64 : field 28 | val sfixed64 : field 29 | val uint32 : field 30 | val fixed32 : field 31 | val uint64 : field 32 | val fixed64 : field 33 | val double : field 34 | val float : field 35 | val string : field 36 | val bytes : field 37 | 38 | val required : string -> message -> field -> int32 -> unit 39 | val optional : ?default:string -> string -> message -> field -> int32 -> unit 40 | val repeated : string -> message -> field -> int32 -> unit 41 | end 42 | 43 | module Generate : sig 44 | include GEN 45 | val write : Format.formatter -> message list -> enum list -> unit 46 | end = 47 | struct 48 | [@@@ocaml.warning "-34"] 49 | let ocaml_keywords = [ 50 | "and"; "as"; "assert"; "asr"; "begin"; "class"; "constraint"; 51 | "do"; "done"; "downto"; "effect"; "else"; "end"; "exception"; 52 | "external"; "false"; "for"; "fun"; "function"; "functor"; "if"; 53 | "implicit"; "in"; "include"; "inherit"; "initializer"; "land"; 54 | "lazy"; "let"; "lor"; "lsl"; "lsr"; "lxor"; "macro"; "match"; 55 | "method"; "mod"; "module"; "mutable"; "new"; "object"; "of"; 56 | "open"; "or"; "private"; "rec"; "sig"; "struct"; "then"; "to"; 57 | "true"; "try"; "type"; "val"; "virtual"; "when"; "with"; "while" 58 | ] 59 | 60 | let safe_id id = if List.mem id ocaml_keywords then id ^ "_" else id 61 | 62 | type message = { 63 | message_name: string; 64 | mutable fields: message_field list; 65 | } 66 | and enum = { 67 | enum_name: string; 68 | mutable constants: (string * int32) list; 69 | } 70 | and field = 71 | Message of message 72 | | Enum of enum 73 | | Basic of basic 74 | and message_field = { 75 | field_name: string; 76 | field_number: int32; 77 | field_type: field; 78 | field_class: [`required | `optional of string option | `repeated] 79 | } 80 | and method_ = { 81 | method_name: string; 82 | input_type: string; 83 | output_type: string; 84 | } 85 | and basic = { 86 | basic_type: string; 87 | basic_constructor: string; 88 | } 89 | let basic typ c : field = Basic { basic_type=typ; basic_constructor=c } 90 | let message name : message = { message_name=name; fields = [] } 91 | and enum name : enum = { enum_name=name; constants = [] } 92 | and constant name enum value = enum.constants <- (name, value) :: enum.constants 93 | and enum_field e = Enum e 94 | and message_field m = Message m 95 | and bool = basic "bool" "bool" 96 | and int32 = basic "int32" "int32" 97 | and sint32 = basic "int32" "sint32" 98 | and sfixed32 = basic "int32" "sfixed32" 99 | and int64 = basic "int64" "int64" 100 | and sint64 = basic "int64" "sint64" 101 | and sfixed64 = basic "int64" "sfixed64" 102 | and uint32 = basic "uint32" "uint32" 103 | and fixed32 = basic "uint32" "fixed32" 104 | and uint64 = basic "uint64" "uint64" 105 | and fixed64 = basic "uint64" "fixed64" 106 | and double = basic "double" "double" 107 | and float = basic "float" "float" 108 | and string = basic "string" "string" 109 | and bytes = basic "Bytes.t" "bytes" 110 | and required field_name msg field_type field_number = 111 | msg.fields <- { field_name; field_type; field_number; field_class = `required } :: msg.fields 112 | and optional ?default field_name msg field_type field_number = 113 | msg.fields <- { field_name; field_type; field_number; field_class = `optional default } :: msg.fields 114 | and repeated field_name msg field_type field_number = 115 | msg.fields <- { field_name; field_type; field_number; field_class = `repeated } :: msg.fields 116 | 117 | let default_value typ fmt s = 118 | Format.fprintf fmt "%s" 119 | (match typ, s with 120 | | Message _m, _ -> failf "Default values of message type are not supported" 121 | | Enum e, n when List.mem_assoc n e.constants -> 122 | let module_name = String.capitalize_ascii e.enum_name in 123 | let constant_name = String.lowercase_ascii n in 124 | Printf.sprintf "%s__constants.%s" module_name constant_name 125 | | Enum e, n -> failf "%s is not a member of enum %s\n" n e.enum_name 126 | | Basic {basic_type="bool";_}, "false" -> "false" 127 | | Basic {basic_type="bool";_}, "true" -> "true" 128 | | Basic {basic_type=t;_}, v -> 129 | Printf.sprintf "(assert false) (* %s of type %s *)" v t) 130 | 131 | let write_class field_type fmt = function 132 | | `required -> Format.pp_print_string fmt "required" 133 | | `optional None -> Format.pp_print_string fmt "optional" 134 | | `optional (Some d) -> Format.fprintf fmt "optional@ ~default:%a" (default_value field_type) d 135 | | `repeated -> Format.pp_print_string fmt "repeated" 136 | 137 | let write_field ~qualify fmt = function 138 | | Message {message_name;_} when qualify -> 139 | Format.fprintf fmt "Types_.s_%s" (String.capitalize_ascii message_name) 140 | | Message {message_name;_} -> 141 | Format.fprintf fmt "s_%s" (String.capitalize_ascii message_name) 142 | | Enum {enum_name;_} when qualify -> 143 | Format.fprintf fmt "@[Types_.%s.e@ Pb.enum@]" (String.capitalize_ascii enum_name) 144 | | Enum {enum_name;_} -> 145 | Format.fprintf fmt "@[%s.e@ Pb.enum@]" (String.capitalize_ascii enum_name) 146 | | Basic s -> 147 | Format.fprintf fmt "%s" s.basic_type 148 | 149 | let max_length = List.fold_left (fun l s -> max (String.length s) l) 0 150 | 151 | let write_record_field_type ~qualify fmt (cls, typ) = match cls with 152 | | `required -> (write_field ~qualify) fmt typ 153 | | `optional None -> Format.fprintf fmt "@[%a@ option@]" (write_field ~qualify) typ 154 | | `optional (Some _) -> Format.fprintf fmt "@[%a@]" (write_field ~qualify) typ 155 | | `repeated -> Format.fprintf fmt "@[%a@ list@]" (write_field ~qualify) typ 156 | 157 | let write_record_rhs ~qualify fmt fields = 158 | let pr f = Format.fprintf fmt f in 159 | ListLabels.iter fields ~f:begin fun {field_name; field_type; field_class; _} -> 160 | pr "@ @ @[%s:@ %a@];@\n" 161 | (safe_id field_name) (write_record_field_type ~qualify) (field_class, field_type); 162 | end 163 | 164 | let write_message fmt { message_name; fields } = 165 | let pr f = Format.fprintf fmt f in 166 | let module_name = String.capitalize_ascii message_name in 167 | pr "@[module@ %s@ =@ struct@\n" module_name; 168 | pr "@ @[include Types_.Fields__%s@]@\n@\n" module_name; 169 | pr "@ @[type s = Types_.s_%s = {@\n%a}@]@\n" module_name (write_record_rhs ~qualify:true) fields; 170 | pr "@\n"; 171 | 172 | (* 173 | Sample target code: 174 | 175 | type s = { 176 | ctype: CType.T.e enum; 177 | packed: bool option; 178 | jstype: JSType.T.e enum; 179 | lazy_: bool; 180 | deprecated: bool; 181 | weak: bool; 182 | uninterpreted_option: UninterpretedOption.s list; 183 | } 184 | 185 | let extract msg = { 186 | ctype = from_opt ~default:CType.string (getf msg ctype); 187 | packed = getf msg packed; 188 | jstype = from_opt ~default:JSType.normal (getf msg jstype); 189 | lazy_ = from_opt ~default:false (getf msg lazy_); 190 | deprecated = from_opt ~default:false (getf msg deprecated); 191 | weak = from_opt ~default:false (getf msg weak); 192 | uninterpreted_option = List.map UninterpretedOption.extract (getf msg uninterpreted_option); 193 | } 194 | *) 195 | pr "@ @[let@ extract@ =@ Types_.extract_%s@]@\n@\n" module_name; 196 | 197 | (* 198 | Sample target code: 199 | 200 | let mk ?ctype:x0 ?packed:x1 ?jstype:x2 ?lazy_:x3 ?deprecated:x4 ?weak:x5 ~uninterpreted_option:x6 () = 201 | let msg = create T.t in 202 | setf msg ctype x0; 203 | setf msg packed x1; 204 | setf msg jstype x2; 205 | setf msg lazy_ x3; 206 | setf msg deprecated x4; 207 | setf msg weak x5; 208 | setf msg uninterpreted_option x6; 209 | msg 210 | *) 211 | let arg cls i name = 212 | match cls with 213 | | `required | `repeated -> 214 | pr "@[~%s:_local%d@]@ " (safe_id name) i 215 | | `optional _ -> 216 | pr "@[?%s:_local%d@]@ " (safe_id name) i 217 | (* TODO: we could use default arguments here: *) 218 | (* 219 | | `optional None -> 220 | pr "@[?%s:_local%d@]@ " (safe_id name) i 221 | | `optional (Some default) -> 222 | pr "@[?%s:(_local%d=%s)@]@ " (safe_id name) i default 223 | *) 224 | in 225 | 226 | pr "@ @[let@ @[mk@ "; 227 | ListLabels.iteri fields ~f:begin 228 | fun i {field_name; field_class; _} -> 229 | arg field_class i field_name 230 | end; 231 | pr "@ ()@ =@]@\n"; 232 | 233 | pr "@ let@ _msg@ =@ @[Pb.create@ T.t@]@ in@\n"; 234 | 235 | ListLabels.iteri fields ~f:begin 236 | fun i {field_name; field_number=_; field_type=_; field_class=_} -> 237 | pr "@ @[Pb.setf@ _msg@ %s@ _local%d@];@\n" (safe_id field_name) i 238 | end; 239 | pr "@ _msg@]@\n"; 240 | 241 | 242 | pr "end@]@\n@\n" 243 | 244 | (* Mutual recursion: what can depend on what? 245 | 246 | type declarations 'module T = ...' do not depend on anything 247 | 248 | field declarations 'let x = T.required ...' may depend on any type declaration and on enum constants 249 | 250 | s declarations may depend on any type declaration 251 | 252 | extract declarations may depend on 253 | any type declaration 254 | and any extract declaration 255 | and any s declaration 256 | and any field declaration 257 | 258 | mk declarations may depend on 259 | the type declaration 260 | and the field declaration for the type 261 | *) 262 | 263 | let write_forward_declarations fmt messages enums = 264 | let pr f = Format.fprintf fmt f in 265 | (* Pb.message bindings *) 266 | pr "module@ Types_@ =@ struct@\n@["; 267 | ListLabels.iter messages ~f:begin fun { message_name; _ } -> 268 | let module_name = String.capitalize_ascii message_name in 269 | pr "@ @[module@ %s@ =@ @[(val@ Pb.message@ %S)@]@]" module_name module_name; 270 | end; 271 | ListLabels.iter enums ~f:begin fun { enum_name; _ } -> 272 | let module_name = String.capitalize_ascii enum_name in 273 | pr "@ @[module@ %s@ =@ @[(val@ Pb.enum@ %S)@]@]" module_name module_name; 274 | end; 275 | ListLabels.iter enums ~f:begin fun { enum_name; constants } -> 276 | let module_name = String.capitalize_ascii enum_name in 277 | pr "@ @[module@ %s__constants@ =@ @[struct@\n" module_name; 278 | ListLabels.iter (List.rev constants) ~f:begin fun (name, value) -> 279 | pr "@[@ let@ %s@ = %s.constant@ %S@ %ldl@]@\n" 280 | (String.lowercase_ascii name) module_name name value; 281 | end; 282 | pr "end@]@]@\n"; 283 | end; 284 | 285 | (* name bindings *) 286 | let write_field_type fmt typ = 287 | match typ with 288 | Basic b -> Format.fprintf fmt "Pb.%s" b.basic_constructor 289 | | Message m -> Format.fprintf fmt "(Pb.msg@ %s.t)" 290 | (String.capitalize_ascii m.message_name) 291 | | Enum e -> Format.fprintf fmt "%s.t" 292 | (String.capitalize_ascii e.enum_name) 293 | in 294 | 295 | ListLabels.iter messages ~f:begin fun { message_name; fields; _ } -> 296 | let module_name = String.capitalize_ascii message_name in 297 | pr "@ @[module@ Fields__%s@ =@ struct@\n" message_name; 298 | pr "@ @[module@ T@ =@ %s@]@\n@\n" module_name; 299 | let max_field_name_length = max_length 300 | (List.map (fun {field_name;_} -> field_name) fields) in 301 | ListLabels.iter (List.rev fields) ~f:begin 302 | fun {field_name; field_number; field_type; field_class} -> 303 | pr "@ @[let@ %s%*s@ @[T.%a@ %a@ %S@ %ld@]@]@\n" 304 | (safe_id field_name) (2 + (max_field_name_length - String.length field_name)) "=" 305 | (write_class field_type) field_class 306 | write_field_type field_type 307 | field_name 308 | field_number 309 | ; 310 | end; 311 | pr "@\nend@\n@]@\n"; 312 | end; 313 | 314 | 315 | (* type s bindings *) 316 | ListLabels.iteri messages ~f:begin fun i { message_name; fields; _ } -> 317 | let module_name = String.capitalize_ascii message_name in 318 | pr "@ @[%s@ s_%s@ =@ {@\n" (if i = 0 then "type" else "and") module_name; 319 | write_record_rhs ~qualify:false fmt fields; 320 | pr "}@]"; 321 | end; 322 | 323 | (* extract bindings *) 324 | 325 | let field_expr cls typ name = 326 | match cls, typ with 327 | | `required, Message m -> 328 | pr "@[extract_%s@ (Pb.getf@ _msg@ %s)@]" 329 | (String.capitalize_ascii m.message_name) 330 | (safe_id name) 331 | | `required, _ -> 332 | pr "@[Pb.getf@ _msg@ %s@]" (safe_id name) 333 | | `repeated, Message m -> 334 | pr "@[List.map@ extract_%s@ @[(Pb.getf@ _msg@ %s)@]@]" 335 | (String.capitalize_ascii m.message_name) name 336 | | `repeated, Enum _ -> 337 | (* pr "@[List.map@ %s.extract@ @[(Pb.getf@ _msg@ %s)@]@]" e.enum_name name *) 338 | pr "@[(Pb.getf@ _msg@ %s)@]" name 339 | | `repeated, Basic _ -> 340 | pr "@[Pb.getf@ _msg@ %s@]" name 341 | | `optional None, Message m -> 342 | pr "@[opt_map extract_%s @[(Pb.getf@ _msg@ %s)@]@]" 343 | (String.capitalize_ascii m.message_name) name 344 | | `optional None, _ -> 345 | pr "@[Pb.getf@ _msg@ %s@]" name 346 | | `optional (Some default), _ -> 347 | pr "@[from_opt@ ~default:%a@ (Pb.getf@ _msg@ %s)@]" (default_value typ) default name 348 | in 349 | 350 | 351 | ListLabels.iteri messages ~f:begin fun i { message_name; fields; _ } -> 352 | let module_name = String.capitalize_ascii message_name in 353 | pr "@ @[%s@ extract_%s@ _msg@ =@ Fields__%s.(({@\n" 354 | (if i = 0 then "let rec" else "and") 355 | module_name 356 | module_name; 357 | ListLabels.iter (List.rev fields) ~f:begin 358 | fun {field_name; field_type; field_class; _} -> 359 | pr "@ @ @[%s@ =@ " (safe_id field_name); 360 | field_expr field_class field_type (safe_id field_name); 361 | pr "@];@\n"; 362 | end; 363 | pr "}@ : s_%s))@]" module_name; 364 | end; 365 | 366 | pr "@]@\nend@\n@\n" 367 | 368 | let write_prologue fmt = 369 | let pr f = Format.fprintf fmt f in 370 | begin 371 | pr "@[(* Generated by ocaml-pb-plugin *)@]@\n@\n"; 372 | pr "[@@@@@@ocaml.warning \"-30\"] (* record labels reused *)@\n@\n"; 373 | pr "open Unsigned@\n"; 374 | pr "module type TRANSPORT = sig end@\n"; 375 | pr "type double = float@\n"; 376 | pr "let from_opt ~default = function Some v -> v | None -> default@\n"; 377 | pr "let opt_map f = function Some v -> Some (f v) | None -> None@\n"; 378 | pr "let rassoc y l = fst (List.find (fun (_,y') -> y = y') l)@\n"; 379 | pr "@\n"; 380 | end 381 | 382 | let write_enum fmt { enum_name; constants } = 383 | let pr f = Format.fprintf fmt f in 384 | let module_name = String.capitalize_ascii enum_name in 385 | begin 386 | pr "module@ %s@ =@ @[struct@\n" module_name; 387 | pr "@[module T = struct@\n@[@;@;"; 388 | 389 | pr "@[type@ e@ =@ Types_.%s.e@]@\n" module_name; 390 | 391 | pr "@[let@ __map@ =@ ["; 392 | ListLabels.iter (List.rev constants) ~f:begin fun (name, v) -> 393 | pr "@\n@ @[%ldl,@ `%s@];" v name; 394 | end; 395 | pr "@]@\n]@\n"; 396 | pr "@[let of_value x = List.assoc x __map@]@\n"; 397 | pr "@[let to_value x = rassoc x __map@]"; 398 | pr "@]@]@\nend@\n"; 399 | pr "@[include@ Types_.%s__constants@]@\n" module_name; 400 | pr "@]@\nend@\n@\n"; 401 | end 402 | 403 | let write fmt messages enums = 404 | write_prologue fmt; 405 | write_forward_declarations fmt messages enums; 406 | List.iter (write_message fmt) messages; 407 | List.iter (write_enum fmt) enums 408 | end 409 | -------------------------------------------------------------------------------- /src/protoc_messages.ml: -------------------------------------------------------------------------------- 1 | (* Generated by ocaml-pb-plugin *) 2 | 3 | [@@@ocaml.warning "-30"] (* record labels reused *) 4 | 5 | open Unsigned 6 | module type TRANSPORT = sig end 7 | type double = float 8 | let from_opt ~default = function Some v -> v | None -> default 9 | let opt_map f = function Some v -> Some (f v) | None -> None 10 | let rassoc y l = fst (List.find (fun (_,y') -> y = y') l) 11 | 12 | module Types_ = 13 | struct 14 | 15 | module DescriptorProto = (val Pb.message "DescriptorProto") 16 | module ServiceOptions = (val Pb.message "ServiceOptions") 17 | module Location = (val Pb.message "Location") 18 | module File = (val Pb.message "File") 19 | module FileDescriptorSet = (val Pb.message "FileDescriptorSet") 20 | module EnumOptions = (val Pb.message "EnumOptions") 21 | module MethodDescriptorProto = (val Pb.message "MethodDescriptorProto") 22 | module ServiceDescriptorProto = (val Pb.message "ServiceDescriptorProto") 23 | module ReservedRange = (val Pb.message "ReservedRange") 24 | module OneofOptions = (val Pb.message "OneofOptions") 25 | module CodeGeneratorResponse = (val Pb.message "CodeGeneratorResponse") 26 | module GeneratedCodeInfo = (val Pb.message "GeneratedCodeInfo") 27 | module CodeGeneratorRequest = (val Pb.message "CodeGeneratorRequest") 28 | module EnumDescriptorProto = (val Pb.message "EnumDescriptorProto") 29 | module FileOptions = (val Pb.message "FileOptions") 30 | module Annotation = (val Pb.message "Annotation") 31 | module OneofDescriptorProto = (val Pb.message "OneofDescriptorProto") 32 | module EnumValueDescriptorProto = 33 | (val Pb.message "EnumValueDescriptorProto") 34 | module FieldDescriptorProto = (val Pb.message "FieldDescriptorProto") 35 | module SourceCodeInfo = (val Pb.message "SourceCodeInfo") 36 | module FieldOptions = (val Pb.message "FieldOptions") 37 | module EnumValueOptions = (val Pb.message "EnumValueOptions") 38 | module UninterpretedOption = (val Pb.message "UninterpretedOption") 39 | module ExtensionRange = (val Pb.message "ExtensionRange") 40 | module MessageOptions = (val Pb.message "MessageOptions") 41 | module MethodOptions = (val Pb.message "MethodOptions") 42 | module FileDescriptorProto = (val Pb.message "FileDescriptorProto") 43 | module NamePart = (val Pb.message "NamePart") 44 | module Version = (val Pb.message "Version") 45 | module OptimizeMode = (val Pb.enum "OptimizeMode") 46 | module Label = (val Pb.enum "Label") 47 | module Type = (val Pb.enum "Type") 48 | module JSType = (val Pb.enum "JSType") 49 | module IdempotencyLevel = (val Pb.enum "IdempotencyLevel") 50 | module CType = (val Pb.enum "CType") 51 | module OptimizeMode__constants = 52 | struct 53 | let speed = OptimizeMode.constant "SPEED" 1l 54 | let code_size = OptimizeMode.constant "CODE_SIZE" 2l 55 | let lite_runtime = OptimizeMode.constant "LITE_RUNTIME" 3l 56 | end 57 | 58 | module Label__constants = 59 | struct 60 | let label_optional = Label.constant "LABEL_OPTIONAL" 1l 61 | let label_required = Label.constant "LABEL_REQUIRED" 2l 62 | let label_repeated = Label.constant "LABEL_REPEATED" 3l 63 | end 64 | 65 | module Type__constants = 66 | struct 67 | let type_double = Type.constant "TYPE_DOUBLE" 1l 68 | let type_float = Type.constant "TYPE_FLOAT" 2l 69 | let type_int64 = Type.constant "TYPE_INT64" 3l 70 | let type_uint64 = Type.constant "TYPE_UINT64" 4l 71 | let type_int32 = Type.constant "TYPE_INT32" 5l 72 | let type_fixed64 = Type.constant "TYPE_FIXED64" 6l 73 | let type_fixed32 = Type.constant "TYPE_FIXED32" 7l 74 | let type_bool = Type.constant "TYPE_BOOL" 8l 75 | let type_string = Type.constant "TYPE_STRING" 9l 76 | let type_group = Type.constant "TYPE_GROUP" 10l 77 | let type_message = Type.constant "TYPE_MESSAGE" 11l 78 | let type_bytes = Type.constant "TYPE_BYTES" 12l 79 | let type_uint32 = Type.constant "TYPE_UINT32" 13l 80 | let type_enum = Type.constant "TYPE_ENUM" 14l 81 | let type_sfixed32 = Type.constant "TYPE_SFIXED32" 15l 82 | let type_sfixed64 = Type.constant "TYPE_SFIXED64" 16l 83 | let type_sint32 = Type.constant "TYPE_SINT32" 17l 84 | let type_sint64 = Type.constant "TYPE_SINT64" 18l 85 | end 86 | 87 | module JSType__constants = 88 | struct 89 | let js_normal = JSType.constant "JS_NORMAL" 0l 90 | let js_string = JSType.constant "JS_STRING" 1l 91 | let js_number = JSType.constant "JS_NUMBER" 2l 92 | end 93 | 94 | module IdempotencyLevel__constants = 95 | struct 96 | let idempotency_unknown = IdempotencyLevel.constant "IDEMPOTENCY_UNKNOWN" 97 | 0l 98 | let no_side_effects = IdempotencyLevel.constant "NO_SIDE_EFFECTS" 1l 99 | let idempotent = IdempotencyLevel.constant "IDEMPOTENT" 2l 100 | end 101 | 102 | module CType__constants = 103 | struct 104 | let string = CType.constant "STRING" 0l 105 | let cord = CType.constant "CORD" 1l 106 | let string_piece = CType.constant "STRING_PIECE" 2l 107 | end 108 | 109 | module Fields__DescriptorProto = struct 110 | module T = DescriptorProto 111 | 112 | let name = T.optional Pb.string "name" 1 113 | let field = T.repeated (Pb.msg FieldDescriptorProto.t) "field" 2 114 | let extension = 115 | T.repeated (Pb.msg FieldDescriptorProto.t) "extension" 6 116 | let nested_type = 117 | T.repeated (Pb.msg DescriptorProto.t) "nested_type" 3 118 | let enum_type = 119 | T.repeated (Pb.msg EnumDescriptorProto.t) "enum_type" 4 120 | let extension_range = 121 | T.repeated (Pb.msg ExtensionRange.t) "extension_range" 5 122 | let oneof_decl = 123 | T.repeated (Pb.msg OneofDescriptorProto.t) "oneof_decl" 8 124 | let options = T.optional (Pb.msg MessageOptions.t) "options" 7 125 | let reserved_range = 126 | T.repeated (Pb.msg ReservedRange.t) "reserved_range" 9 127 | let reserved_name = T.repeated Pb.string "reserved_name" 10 128 | 129 | end 130 | 131 | 132 | module Fields__ServiceOptions = struct 133 | module T = ServiceOptions 134 | 135 | let deprecated = 136 | T.optional ~default:false Pb.bool "deprecated" 33 137 | let uninterpreted_option = 138 | T.repeated (Pb.msg UninterpretedOption.t) "uninterpreted_option" 999 139 | 140 | end 141 | 142 | 143 | module Fields__Location = struct 144 | module T = Location 145 | 146 | let path = T.repeated Pb.int32 "path" 1 147 | let span = T.repeated Pb.int32 "span" 2 148 | let leading_comments = T.optional Pb.string "leading_comments" 3 149 | let trailing_comments = T.optional Pb.string "trailing_comments" 4 150 | let leading_detached_comments = 151 | T.repeated Pb.string "leading_detached_comments" 6 152 | 153 | end 154 | 155 | 156 | module Fields__File = struct 157 | module T = File 158 | 159 | let name = T.optional Pb.string "name" 1 160 | let insertion_point = T.optional Pb.string "insertion_point" 2 161 | let content = T.optional Pb.string "content" 15 162 | 163 | end 164 | 165 | 166 | module Fields__FileDescriptorSet = struct 167 | module T = FileDescriptorSet 168 | 169 | let file = T.repeated (Pb.msg FileDescriptorProto.t) "file" 1 170 | 171 | end 172 | 173 | 174 | module Fields__EnumOptions = struct 175 | module T = EnumOptions 176 | 177 | let allow_alias = T.optional Pb.bool "allow_alias" 2 178 | let deprecated = 179 | T.optional ~default:false Pb.bool "deprecated" 3 180 | let uninterpreted_option = 181 | T.repeated (Pb.msg UninterpretedOption.t) "uninterpreted_option" 999 182 | 183 | end 184 | 185 | 186 | module Fields__MethodDescriptorProto = struct 187 | module T = MethodDescriptorProto 188 | 189 | let name = T.optional Pb.string "name" 1 190 | let input_type = T.optional Pb.string "input_type" 2 191 | let output_type = T.optional Pb.string "output_type" 3 192 | let options = T.optional (Pb.msg MethodOptions.t) "options" 4 193 | let client_streaming = 194 | T.optional ~default:false Pb.bool "client_streaming" 5 195 | let server_streaming = 196 | T.optional ~default:false Pb.bool "server_streaming" 6 197 | 198 | end 199 | 200 | 201 | module Fields__ServiceDescriptorProto = struct 202 | module T = ServiceDescriptorProto 203 | 204 | let name = T.optional Pb.string "name" 1 205 | let method_ = T.repeated (Pb.msg MethodDescriptorProto.t) "method" 2 206 | let options = T.optional (Pb.msg ServiceOptions.t) "options" 3 207 | 208 | end 209 | 210 | 211 | module Fields__ReservedRange = struct 212 | module T = ReservedRange 213 | 214 | let start = T.optional Pb.int32 "start" 1 215 | let end_ = T.optional Pb.int32 "end" 2 216 | 217 | end 218 | 219 | 220 | module Fields__OneofOptions = struct 221 | module T = OneofOptions 222 | 223 | let uninterpreted_option = 224 | T.repeated (Pb.msg UninterpretedOption.t) "uninterpreted_option" 999 225 | 226 | end 227 | 228 | 229 | module Fields__CodeGeneratorResponse = struct 230 | module T = CodeGeneratorResponse 231 | 232 | let error = T.optional Pb.string "error" 1 233 | let file = T.repeated (Pb.msg File.t) "file" 15 234 | 235 | end 236 | 237 | 238 | module Fields__GeneratedCodeInfo = struct 239 | module T = GeneratedCodeInfo 240 | 241 | let annotation = T.repeated (Pb.msg Annotation.t) "annotation" 1 242 | 243 | end 244 | 245 | 246 | module Fields__CodeGeneratorRequest = struct 247 | module T = CodeGeneratorRequest 248 | 249 | let file_to_generate = T.repeated Pb.string "file_to_generate" 1 250 | let parameter = T.optional Pb.string "parameter" 2 251 | let proto_file = 252 | T.repeated (Pb.msg FileDescriptorProto.t) "proto_file" 15 253 | let compiler_version = T.optional (Pb.msg Version.t) "compiler_version" 3 254 | 255 | end 256 | 257 | 258 | module Fields__EnumDescriptorProto = struct 259 | module T = EnumDescriptorProto 260 | 261 | let name = T.optional Pb.string "name" 1 262 | let value = T.repeated (Pb.msg EnumValueDescriptorProto.t) "value" 2 263 | let options = T.optional (Pb.msg EnumOptions.t) "options" 3 264 | 265 | end 266 | 267 | 268 | module Fields__FileOptions = struct 269 | module T = FileOptions 270 | 271 | let java_package = T.optional Pb.string "java_package" 1 272 | let java_outer_classname = 273 | T.optional Pb.string "java_outer_classname" 8 274 | let java_multiple_files = 275 | T.optional ~default:false Pb.bool "java_multiple_files" 10 276 | let java_generate_equals_and_hash = 277 | T.optional Pb.bool "java_generate_equals_and_hash" 20 278 | let java_string_check_utf8 = 279 | T.optional ~default:false Pb.bool "java_string_check_utf8" 27 280 | let optimize_for = 281 | T.optional ~default:OptimizeMode__constants.speed OptimizeMode.t 282 | "optimize_for" 9 283 | let go_package = T.optional Pb.string "go_package" 11 284 | let cc_generic_services = 285 | T.optional ~default:false Pb.bool "cc_generic_services" 16 286 | let java_generic_services = 287 | T.optional ~default:false Pb.bool "java_generic_services" 17 288 | let py_generic_services = 289 | T.optional ~default:false Pb.bool "py_generic_services" 18 290 | let deprecated = 291 | T.optional ~default:false Pb.bool "deprecated" 23 292 | let cc_enable_arenas = 293 | T.optional ~default:false Pb.bool "cc_enable_arenas" 31 294 | let objc_class_prefix = 295 | T.optional Pb.string "objc_class_prefix" 36 296 | let csharp_namespace = 297 | T.optional Pb.string "csharp_namespace" 37 298 | let swift_prefix = T.optional Pb.string "swift_prefix" 39 299 | let uninterpreted_option = 300 | T.repeated (Pb.msg UninterpretedOption.t) "uninterpreted_option" 999 301 | 302 | end 303 | 304 | 305 | module Fields__Annotation = struct 306 | module T = Annotation 307 | 308 | let path = T.repeated Pb.int32 "path" 1 309 | let source_file = T.optional Pb.string "source_file" 2 310 | let begin_ = T.optional Pb.int32 "begin" 3 311 | let end_ = T.optional Pb.int32 "end" 4 312 | 313 | end 314 | 315 | 316 | module Fields__OneofDescriptorProto = struct 317 | module T = OneofDescriptorProto 318 | 319 | let name = T.optional Pb.string "name" 1 320 | let options = T.optional (Pb.msg OneofOptions.t) "options" 2 321 | 322 | end 323 | 324 | 325 | module Fields__EnumValueDescriptorProto = struct 326 | module T = EnumValueDescriptorProto 327 | 328 | let name = T.optional Pb.string "name" 1 329 | let number = T.optional Pb.int32 "number" 2 330 | let options = T.optional (Pb.msg EnumValueOptions.t) "options" 3 331 | 332 | end 333 | 334 | 335 | module Fields__FieldDescriptorProto = struct 336 | module T = FieldDescriptorProto 337 | 338 | let name = T.optional Pb.string "name" 1 339 | let number = T.optional Pb.int32 "number" 3 340 | let label = T.optional Label.t "label" 4 341 | let type_ = T.optional Type.t "type" 5 342 | let type_name = T.optional Pb.string "type_name" 6 343 | let extendee = T.optional Pb.string "extendee" 2 344 | let default_value = T.optional Pb.string "default_value" 7 345 | let oneof_index = T.optional Pb.int32 "oneof_index" 9 346 | let json_name = T.optional Pb.string "json_name" 10 347 | let options = T.optional (Pb.msg FieldOptions.t) "options" 8 348 | 349 | end 350 | 351 | 352 | module Fields__SourceCodeInfo = struct 353 | module T = SourceCodeInfo 354 | 355 | let location = T.repeated (Pb.msg Location.t) "location" 1 356 | 357 | end 358 | 359 | 360 | module Fields__FieldOptions = struct 361 | module T = FieldOptions 362 | 363 | let ctype = 364 | T.optional ~default:CType__constants.string CType.t "ctype" 1 365 | let packed = T.optional Pb.bool "packed" 2 366 | let jstype = 367 | T.optional ~default:JSType__constants.js_normal JSType.t "jstype" 6 368 | let lazy_ = T.optional ~default:false Pb.bool "lazy" 5 369 | let deprecated = 370 | T.optional ~default:false Pb.bool "deprecated" 3 371 | let weak = T.optional ~default:false Pb.bool "weak" 10 372 | let uninterpreted_option = 373 | T.repeated (Pb.msg UninterpretedOption.t) "uninterpreted_option" 999 374 | 375 | end 376 | 377 | 378 | module Fields__EnumValueOptions = struct 379 | module T = EnumValueOptions 380 | 381 | let deprecated = 382 | T.optional ~default:false Pb.bool "deprecated" 1 383 | let uninterpreted_option = 384 | T.repeated (Pb.msg UninterpretedOption.t) "uninterpreted_option" 999 385 | 386 | end 387 | 388 | 389 | module Fields__UninterpretedOption = struct 390 | module T = UninterpretedOption 391 | 392 | let name = T.repeated (Pb.msg NamePart.t) "name" 2 393 | let identifier_value = T.optional Pb.string "identifier_value" 3 394 | let positive_int_value = T.optional Pb.uint64 "positive_int_value" 4 395 | let negative_int_value = T.optional Pb.int64 "negative_int_value" 5 396 | let double_value = T.optional Pb.double "double_value" 6 397 | let string_value = T.optional Pb.bytes "string_value" 7 398 | let aggregate_value = T.optional Pb.string "aggregate_value" 8 399 | 400 | end 401 | 402 | 403 | module Fields__ExtensionRange = struct 404 | module T = ExtensionRange 405 | 406 | let start = T.optional Pb.int32 "start" 1 407 | let end_ = T.optional Pb.int32 "end" 2 408 | 409 | end 410 | 411 | 412 | module Fields__MessageOptions = struct 413 | module T = MessageOptions 414 | 415 | let message_set_wire_format = 416 | T.optional ~default:false Pb.bool "message_set_wire_format" 1 417 | let no_standard_descriptor_accessor = 418 | T.optional ~default:false Pb.bool "no_standard_descriptor_accessor" 2 419 | let deprecated = 420 | T.optional ~default:false Pb.bool "deprecated" 3 421 | let map_entry = T.optional Pb.bool "map_entry" 7 422 | let uninterpreted_option = 423 | T.repeated (Pb.msg UninterpretedOption.t) "uninterpreted_option" 999 424 | 425 | end 426 | 427 | 428 | module Fields__MethodOptions = struct 429 | module T = MethodOptions 430 | 431 | let deprecated = 432 | T.optional ~default:false Pb.bool "deprecated" 33 433 | let idempotency_level = 434 | T.optional ~default:IdempotencyLevel__constants.idempotency_unknown 435 | IdempotencyLevel.t "idempotency_level" 34 436 | let uninterpreted_option = 437 | T.repeated (Pb.msg UninterpretedOption.t) "uninterpreted_option" 999 438 | 439 | end 440 | 441 | 442 | module Fields__FileDescriptorProto = struct 443 | module T = FileDescriptorProto 444 | 445 | let name = T.optional Pb.string "name" 1 446 | let package = T.optional Pb.string "package" 2 447 | let dependency = T.repeated Pb.string "dependency" 3 448 | let public_dependency = T.repeated Pb.int32 "public_dependency" 10 449 | let weak_dependency = T.repeated Pb.int32 "weak_dependency" 11 450 | let message_type = 451 | T.repeated (Pb.msg DescriptorProto.t) "message_type" 4 452 | let enum_type = 453 | T.repeated (Pb.msg EnumDescriptorProto.t) "enum_type" 5 454 | let service = 455 | T.repeated (Pb.msg ServiceDescriptorProto.t) "service" 6 456 | let extension = 457 | T.repeated (Pb.msg FieldDescriptorProto.t) "extension" 7 458 | let options = T.optional (Pb.msg FileOptions.t) "options" 8 459 | let source_code_info = 460 | T.optional (Pb.msg SourceCodeInfo.t) "source_code_info" 9 461 | let syntax = T.optional Pb.string "syntax" 12 462 | 463 | end 464 | 465 | 466 | module Fields__NamePart = struct 467 | module T = NamePart 468 | 469 | let name_part = T.required Pb.string "name_part" 1 470 | let is_extension = T.required Pb.bool "is_extension" 2 471 | 472 | end 473 | 474 | 475 | module Fields__Version = struct 476 | module T = Version 477 | 478 | let major = T.optional Pb.int32 "major" 1 479 | let minor = T.optional Pb.int32 "minor" 2 480 | let patch = T.optional Pb.int32 "patch" 3 481 | let suffix = T.optional Pb.string "suffix" 4 482 | 483 | end 484 | 485 | 486 | type s_DescriptorProto = { 487 | reserved_name: string list; 488 | reserved_range: s_ReservedRange list; 489 | options: s_MessageOptions option; 490 | oneof_decl: s_OneofDescriptorProto list; 491 | extension_range: s_ExtensionRange list; 492 | enum_type: s_EnumDescriptorProto list; 493 | nested_type: s_DescriptorProto list; 494 | extension: s_FieldDescriptorProto list; 495 | field: s_FieldDescriptorProto list; 496 | name: string option; 497 | } 498 | and s_ServiceOptions = { 499 | uninterpreted_option: s_UninterpretedOption list; 500 | deprecated: bool; 501 | } 502 | and s_Location = { 503 | leading_detached_comments: string list; 504 | trailing_comments: string option; 505 | leading_comments: string option; 506 | span: int32 list; 507 | path: int32 list; 508 | } 509 | and s_File = { 510 | content: string option; 511 | insertion_point: string option; 512 | name: string option; 513 | } 514 | and s_FileDescriptorSet = { 515 | file: s_FileDescriptorProto list; 516 | } 517 | and s_EnumOptions = { 518 | uninterpreted_option: s_UninterpretedOption list; 519 | deprecated: bool; 520 | allow_alias: bool option; 521 | } 522 | and s_MethodDescriptorProto = { 523 | server_streaming: bool; 524 | client_streaming: bool; 525 | options: s_MethodOptions option; 526 | output_type: string option; 527 | input_type: string option; 528 | name: string option; 529 | } 530 | and s_ServiceDescriptorProto = { 531 | options: s_ServiceOptions option; 532 | method_: s_MethodDescriptorProto list; 533 | name: string option; 534 | } 535 | and s_ReservedRange = { 536 | end_: int32 option; 537 | start: int32 option; 538 | } 539 | and s_OneofOptions = { 540 | uninterpreted_option: s_UninterpretedOption list; 541 | } 542 | and s_CodeGeneratorResponse = { 543 | file: s_File list; 544 | error: string option; 545 | } 546 | and s_GeneratedCodeInfo = { 547 | annotation: s_Annotation list; 548 | } 549 | and s_CodeGeneratorRequest = { 550 | compiler_version: s_Version option; 551 | proto_file: s_FileDescriptorProto list; 552 | parameter: string option; 553 | file_to_generate: string list; 554 | } 555 | and s_EnumDescriptorProto = { 556 | options: s_EnumOptions option; 557 | value: s_EnumValueDescriptorProto list; 558 | name: string option; 559 | } 560 | and s_FileOptions = { 561 | uninterpreted_option: s_UninterpretedOption list; 562 | swift_prefix: string option; 563 | csharp_namespace: string option; 564 | objc_class_prefix: string option; 565 | cc_enable_arenas: bool; 566 | deprecated: bool; 567 | py_generic_services: bool; 568 | java_generic_services: bool; 569 | cc_generic_services: bool; 570 | go_package: string option; 571 | optimize_for: OptimizeMode.e Pb.enum; 572 | java_string_check_utf8: bool; 573 | java_generate_equals_and_hash: bool option; 574 | java_multiple_files: bool; 575 | java_outer_classname: string option; 576 | java_package: string option; 577 | } 578 | and s_Annotation = { 579 | end_: int32 option; 580 | begin_: int32 option; 581 | source_file: string option; 582 | path: int32 list; 583 | } 584 | and s_OneofDescriptorProto = { 585 | options: s_OneofOptions option; 586 | name: string option; 587 | } 588 | and s_EnumValueDescriptorProto = { 589 | options: s_EnumValueOptions option; 590 | number: int32 option; 591 | name: string option; 592 | } 593 | and s_FieldDescriptorProto = { 594 | options: s_FieldOptions option; 595 | json_name: string option; 596 | oneof_index: int32 option; 597 | default_value: string option; 598 | extendee: string option; 599 | type_name: string option; 600 | type_: Type.e Pb.enum option; 601 | label: Label.e Pb.enum option; 602 | number: int32 option; 603 | name: string option; 604 | } 605 | and s_SourceCodeInfo = { 606 | location: s_Location list; 607 | } 608 | and s_FieldOptions = { 609 | uninterpreted_option: s_UninterpretedOption list; 610 | weak: bool; 611 | deprecated: bool; 612 | lazy_: bool; 613 | jstype: JSType.e Pb.enum; 614 | packed: bool option; 615 | ctype: CType.e Pb.enum; 616 | } 617 | and s_EnumValueOptions = { 618 | uninterpreted_option: s_UninterpretedOption list; 619 | deprecated: bool; 620 | } 621 | and s_UninterpretedOption = { 622 | aggregate_value: string option; 623 | string_value: Bytes.t option; 624 | double_value: double option; 625 | negative_int_value: int64 option; 626 | positive_int_value: uint64 option; 627 | identifier_value: string option; 628 | name: s_NamePart list; 629 | } 630 | and s_ExtensionRange = { 631 | end_: int32 option; 632 | start: int32 option; 633 | } 634 | and s_MessageOptions = { 635 | uninterpreted_option: s_UninterpretedOption list; 636 | map_entry: bool option; 637 | deprecated: bool; 638 | no_standard_descriptor_accessor: bool; 639 | message_set_wire_format: bool; 640 | } 641 | and s_MethodOptions = { 642 | uninterpreted_option: s_UninterpretedOption list; 643 | idempotency_level: IdempotencyLevel.e Pb.enum; 644 | deprecated: bool; 645 | } 646 | and s_FileDescriptorProto = { 647 | syntax: string option; 648 | source_code_info: s_SourceCodeInfo option; 649 | options: s_FileOptions option; 650 | extension: s_FieldDescriptorProto list; 651 | service: s_ServiceDescriptorProto list; 652 | enum_type: s_EnumDescriptorProto list; 653 | message_type: s_DescriptorProto list; 654 | weak_dependency: int32 list; 655 | public_dependency: int32 list; 656 | dependency: string list; 657 | package: string option; 658 | name: string option; 659 | } 660 | and s_NamePart = { 661 | is_extension: bool; 662 | name_part: string; 663 | } 664 | and s_Version = { 665 | suffix: string option; 666 | patch: int32 option; 667 | minor: int32 option; 668 | major: int32 option; 669 | } 670 | let rec extract_DescriptorProto _msg = Fields__DescriptorProto.(({ 671 | name = Pb.getf _msg name; 672 | field = List.map extract_FieldDescriptorProto (Pb.getf _msg field); 673 | extension = 674 | List.map extract_FieldDescriptorProto (Pb.getf _msg extension); 675 | nested_type = List.map extract_DescriptorProto (Pb.getf _msg nested_type); 676 | enum_type = List.map extract_EnumDescriptorProto (Pb.getf _msg enum_type); 677 | extension_range = 678 | List.map extract_ExtensionRange (Pb.getf _msg extension_range); 679 | oneof_decl = 680 | List.map extract_OneofDescriptorProto (Pb.getf _msg oneof_decl); 681 | options = opt_map extract_MessageOptions (Pb.getf _msg options); 682 | reserved_range = 683 | List.map extract_ReservedRange (Pb.getf _msg reserved_range); 684 | reserved_name = Pb.getf _msg reserved_name; 685 | } : s_DescriptorProto)) 686 | and extract_ServiceOptions _msg = Fields__ServiceOptions.(({ 687 | deprecated = from_opt ~default:false (Pb.getf _msg deprecated); 688 | uninterpreted_option = 689 | List.map extract_UninterpretedOption (Pb.getf _msg uninterpreted_option); 690 | } : s_ServiceOptions)) 691 | and extract_Location _msg = Fields__Location.(({ 692 | path = Pb.getf _msg path; 693 | span = Pb.getf _msg span; 694 | leading_comments = Pb.getf _msg leading_comments; 695 | trailing_comments = Pb.getf _msg trailing_comments; 696 | leading_detached_comments = Pb.getf _msg leading_detached_comments; 697 | } : s_Location)) 698 | and extract_File _msg = Fields__File.(({ 699 | name = Pb.getf _msg name; 700 | insertion_point = Pb.getf _msg insertion_point; 701 | content = Pb.getf _msg content; 702 | } : s_File)) 703 | and extract_FileDescriptorSet _msg = Fields__FileDescriptorSet.(({ 704 | file = List.map extract_FileDescriptorProto (Pb.getf _msg file); 705 | } : s_FileDescriptorSet)) 706 | and extract_EnumOptions _msg = Fields__EnumOptions.(({ 707 | allow_alias = Pb.getf _msg allow_alias; 708 | deprecated = from_opt ~default:false (Pb.getf _msg deprecated); 709 | uninterpreted_option = 710 | List.map extract_UninterpretedOption (Pb.getf _msg uninterpreted_option); 711 | } : s_EnumOptions)) 712 | and extract_MethodDescriptorProto _msg = Fields__MethodDescriptorProto.(({ 713 | name = Pb.getf _msg name; 714 | input_type = Pb.getf _msg input_type; 715 | output_type = Pb.getf _msg output_type; 716 | options = opt_map extract_MethodOptions (Pb.getf _msg options); 717 | client_streaming = 718 | from_opt ~default:false (Pb.getf _msg client_streaming); 719 | server_streaming = 720 | from_opt ~default:false (Pb.getf _msg server_streaming); 721 | } : s_MethodDescriptorProto)) 722 | and extract_ServiceDescriptorProto _msg = 723 | Fields__ServiceDescriptorProto.(({ 724 | name = Pb.getf _msg name; 725 | method_ = List.map extract_MethodDescriptorProto (Pb.getf _msg method_); 726 | options = opt_map extract_ServiceOptions (Pb.getf _msg options); 727 | } : s_ServiceDescriptorProto)) 728 | and extract_ReservedRange _msg = Fields__ReservedRange.(({ 729 | start = Pb.getf _msg start; 730 | end_ = Pb.getf _msg end_; 731 | } : s_ReservedRange)) 732 | and extract_OneofOptions _msg = Fields__OneofOptions.(({ 733 | uninterpreted_option = 734 | List.map extract_UninterpretedOption (Pb.getf _msg uninterpreted_option); 735 | } : s_OneofOptions)) 736 | and extract_CodeGeneratorResponse _msg = Fields__CodeGeneratorResponse.(({ 737 | error = Pb.getf _msg error; 738 | file = List.map extract_File (Pb.getf _msg file); 739 | } : s_CodeGeneratorResponse)) 740 | and extract_GeneratedCodeInfo _msg = Fields__GeneratedCodeInfo.(({ 741 | annotation = List.map extract_Annotation (Pb.getf _msg annotation); 742 | } : s_GeneratedCodeInfo)) 743 | and extract_CodeGeneratorRequest _msg = Fields__CodeGeneratorRequest.(({ 744 | file_to_generate = Pb.getf _msg file_to_generate; 745 | parameter = Pb.getf _msg parameter; 746 | proto_file = 747 | List.map extract_FileDescriptorProto (Pb.getf _msg proto_file); 748 | compiler_version = 749 | opt_map extract_Version (Pb.getf _msg compiler_version); 750 | } : s_CodeGeneratorRequest)) 751 | and extract_EnumDescriptorProto _msg = Fields__EnumDescriptorProto.(({ 752 | name = Pb.getf _msg name; 753 | value = List.map extract_EnumValueDescriptorProto (Pb.getf _msg value); 754 | options = opt_map extract_EnumOptions (Pb.getf _msg options); 755 | } : s_EnumDescriptorProto)) 756 | and extract_FileOptions _msg = Fields__FileOptions.(({ 757 | java_package = Pb.getf _msg java_package; 758 | java_outer_classname = Pb.getf _msg java_outer_classname; 759 | java_multiple_files = 760 | from_opt ~default:false (Pb.getf _msg java_multiple_files); 761 | java_generate_equals_and_hash = 762 | Pb.getf _msg java_generate_equals_and_hash; 763 | java_string_check_utf8 = 764 | from_opt ~default:false (Pb.getf _msg java_string_check_utf8); 765 | optimize_for = 766 | from_opt ~default:OptimizeMode__constants.speed (Pb.getf _msg 767 | optimize_for); 768 | go_package = Pb.getf _msg go_package; 769 | cc_generic_services = 770 | from_opt ~default:false (Pb.getf _msg cc_generic_services); 771 | java_generic_services = 772 | from_opt ~default:false (Pb.getf _msg java_generic_services); 773 | py_generic_services = 774 | from_opt ~default:false (Pb.getf _msg py_generic_services); 775 | deprecated = from_opt ~default:false (Pb.getf _msg deprecated); 776 | cc_enable_arenas = 777 | from_opt ~default:false (Pb.getf _msg cc_enable_arenas); 778 | objc_class_prefix = Pb.getf _msg objc_class_prefix; 779 | csharp_namespace = Pb.getf _msg csharp_namespace; 780 | swift_prefix = Pb.getf _msg swift_prefix; 781 | uninterpreted_option = 782 | List.map extract_UninterpretedOption (Pb.getf _msg uninterpreted_option); 783 | } : s_FileOptions)) 784 | and extract_Annotation _msg = Fields__Annotation.(({ 785 | path = Pb.getf _msg path; 786 | source_file = Pb.getf _msg source_file; 787 | begin_ = Pb.getf _msg begin_; 788 | end_ = Pb.getf _msg end_; 789 | } : s_Annotation)) 790 | and extract_OneofDescriptorProto _msg = Fields__OneofDescriptorProto.(({ 791 | name = Pb.getf _msg name; 792 | options = opt_map extract_OneofOptions (Pb.getf _msg options); 793 | } : s_OneofDescriptorProto)) 794 | and extract_EnumValueDescriptorProto _msg = 795 | Fields__EnumValueDescriptorProto.(({ 796 | name = Pb.getf _msg name; 797 | number = Pb.getf _msg number; 798 | options = opt_map extract_EnumValueOptions (Pb.getf _msg options); 799 | } : s_EnumValueDescriptorProto)) 800 | and extract_FieldDescriptorProto _msg = Fields__FieldDescriptorProto.(({ 801 | name = Pb.getf _msg name; 802 | number = Pb.getf _msg number; 803 | label = Pb.getf _msg label; 804 | type_ = Pb.getf _msg type_; 805 | type_name = Pb.getf _msg type_name; 806 | extendee = Pb.getf _msg extendee; 807 | default_value = Pb.getf _msg default_value; 808 | oneof_index = Pb.getf _msg oneof_index; 809 | json_name = Pb.getf _msg json_name; 810 | options = opt_map extract_FieldOptions (Pb.getf _msg options); 811 | } : s_FieldDescriptorProto)) 812 | and extract_SourceCodeInfo _msg = Fields__SourceCodeInfo.(({ 813 | location = List.map extract_Location (Pb.getf _msg location); 814 | } : s_SourceCodeInfo)) 815 | and extract_FieldOptions _msg = Fields__FieldOptions.(({ 816 | ctype = from_opt ~default:CType__constants.string (Pb.getf _msg ctype); 817 | packed = Pb.getf _msg packed; 818 | jstype = 819 | from_opt ~default:JSType__constants.js_normal (Pb.getf _msg jstype); 820 | lazy_ = from_opt ~default:false (Pb.getf _msg lazy_); 821 | deprecated = from_opt ~default:false (Pb.getf _msg deprecated); 822 | weak = from_opt ~default:false (Pb.getf _msg weak); 823 | uninterpreted_option = 824 | List.map extract_UninterpretedOption (Pb.getf _msg uninterpreted_option); 825 | } : s_FieldOptions)) 826 | and extract_EnumValueOptions _msg = Fields__EnumValueOptions.(({ 827 | deprecated = from_opt ~default:false (Pb.getf _msg deprecated); 828 | uninterpreted_option = 829 | List.map extract_UninterpretedOption (Pb.getf _msg uninterpreted_option); 830 | } : s_EnumValueOptions)) 831 | and extract_UninterpretedOption _msg = Fields__UninterpretedOption.(({ 832 | name = List.map extract_NamePart (Pb.getf _msg name); 833 | identifier_value = Pb.getf _msg identifier_value; 834 | positive_int_value = Pb.getf _msg positive_int_value; 835 | negative_int_value = Pb.getf _msg negative_int_value; 836 | double_value = Pb.getf _msg double_value; 837 | string_value = Pb.getf _msg string_value; 838 | aggregate_value = Pb.getf _msg aggregate_value; 839 | } : s_UninterpretedOption)) 840 | and extract_ExtensionRange _msg = Fields__ExtensionRange.(({ 841 | start = Pb.getf _msg start; 842 | end_ = Pb.getf _msg end_; 843 | } : s_ExtensionRange)) 844 | and extract_MessageOptions _msg = Fields__MessageOptions.(({ 845 | message_set_wire_format = 846 | from_opt ~default:false (Pb.getf _msg message_set_wire_format); 847 | no_standard_descriptor_accessor = 848 | from_opt ~default:false (Pb.getf _msg no_standard_descriptor_accessor); 849 | deprecated = from_opt ~default:false (Pb.getf _msg deprecated); 850 | map_entry = Pb.getf _msg map_entry; 851 | uninterpreted_option = 852 | List.map extract_UninterpretedOption (Pb.getf _msg uninterpreted_option); 853 | } : s_MessageOptions)) 854 | and extract_MethodOptions _msg = Fields__MethodOptions.(({ 855 | deprecated = from_opt ~default:false (Pb.getf _msg deprecated); 856 | idempotency_level = 857 | from_opt ~default:IdempotencyLevel__constants.idempotency_unknown 858 | (Pb.getf _msg idempotency_level); 859 | uninterpreted_option = 860 | List.map extract_UninterpretedOption (Pb.getf _msg uninterpreted_option); 861 | } : s_MethodOptions)) 862 | and extract_FileDescriptorProto _msg = Fields__FileDescriptorProto.(({ 863 | name = Pb.getf _msg name; 864 | package = Pb.getf _msg package; 865 | dependency = Pb.getf _msg dependency; 866 | public_dependency = Pb.getf _msg public_dependency; 867 | weak_dependency = Pb.getf _msg weak_dependency; 868 | message_type = 869 | List.map extract_DescriptorProto (Pb.getf _msg message_type); 870 | enum_type = List.map extract_EnumDescriptorProto (Pb.getf _msg enum_type); 871 | service = List.map extract_ServiceDescriptorProto (Pb.getf _msg service); 872 | extension = 873 | List.map extract_FieldDescriptorProto (Pb.getf _msg extension); 874 | options = opt_map extract_FileOptions (Pb.getf _msg options); 875 | source_code_info = 876 | opt_map extract_SourceCodeInfo (Pb.getf _msg source_code_info); 877 | syntax = Pb.getf _msg syntax; 878 | } : s_FileDescriptorProto)) 879 | and extract_NamePart _msg = Fields__NamePart.(({ 880 | name_part = Pb.getf _msg name_part; 881 | is_extension = Pb.getf _msg is_extension; 882 | } : s_NamePart)) 883 | and extract_Version _msg = Fields__Version.(({ 884 | major = Pb.getf _msg major; 885 | minor = Pb.getf _msg minor; 886 | patch = Pb.getf _msg patch; 887 | suffix = Pb.getf _msg suffix; 888 | } : s_Version)) 889 | end 890 | 891 | module DescriptorProto = struct 892 | include Types_.Fields__DescriptorProto 893 | 894 | type s = Types_.s_DescriptorProto = { 895 | reserved_name: string list; 896 | reserved_range: Types_.s_ReservedRange list; 897 | options: Types_.s_MessageOptions option; 898 | oneof_decl: Types_.s_OneofDescriptorProto list; 899 | extension_range: Types_.s_ExtensionRange list; 900 | enum_type: Types_.s_EnumDescriptorProto list; 901 | nested_type: Types_.s_DescriptorProto list; 902 | extension: Types_.s_FieldDescriptorProto list; 903 | field: Types_.s_FieldDescriptorProto list; 904 | name: string option; 905 | } 906 | 907 | let extract = Types_.extract_DescriptorProto 908 | 909 | let mk ~reserved_name:_local0 ~reserved_range:_local1 ?options:_local2 910 | ~oneof_decl:_local3 ~extension_range:_local4 ~enum_type:_local5 911 | ~nested_type:_local6 ~extension:_local7 ~field:_local8 ?name:_local9 () 912 | = 913 | let _msg = Pb.create T.t in 914 | Pb.setf _msg reserved_name _local0; 915 | Pb.setf _msg reserved_range _local1; 916 | Pb.setf _msg options _local2; 917 | Pb.setf _msg oneof_decl _local3; 918 | Pb.setf _msg extension_range _local4; 919 | Pb.setf _msg enum_type _local5; 920 | Pb.setf _msg nested_type _local6; 921 | Pb.setf _msg extension _local7; 922 | Pb.setf _msg field _local8; 923 | Pb.setf _msg name _local9; 924 | _msg 925 | end 926 | 927 | module ServiceOptions = struct 928 | include Types_.Fields__ServiceOptions 929 | 930 | type s = Types_.s_ServiceOptions = { 931 | uninterpreted_option: Types_.s_UninterpretedOption list; 932 | deprecated: bool; 933 | } 934 | 935 | let extract = Types_.extract_ServiceOptions 936 | 937 | let mk ~uninterpreted_option:_local0 ?deprecated:_local1 () = 938 | let _msg = Pb.create T.t in 939 | Pb.setf _msg uninterpreted_option _local0; 940 | Pb.setf _msg deprecated _local1; 941 | _msg 942 | end 943 | 944 | module Location = struct 945 | include Types_.Fields__Location 946 | 947 | type s = Types_.s_Location = { 948 | leading_detached_comments: string list; 949 | trailing_comments: string option; 950 | leading_comments: string option; 951 | span: int32 list; 952 | path: int32 list; 953 | } 954 | 955 | let extract = Types_.extract_Location 956 | 957 | let mk ~leading_detached_comments:_local0 ?trailing_comments:_local1 958 | ?leading_comments:_local2 ~span:_local3 ~path:_local4 () = 959 | let _msg = Pb.create T.t in 960 | Pb.setf _msg leading_detached_comments _local0; 961 | Pb.setf _msg trailing_comments _local1; 962 | Pb.setf _msg leading_comments _local2; 963 | Pb.setf _msg span _local3; 964 | Pb.setf _msg path _local4; 965 | _msg 966 | end 967 | 968 | module File = struct 969 | include Types_.Fields__File 970 | 971 | type s = Types_.s_File = { 972 | content: string option; 973 | insertion_point: string option; 974 | name: string option; 975 | } 976 | 977 | let extract = Types_.extract_File 978 | 979 | let mk ?content:_local0 ?insertion_point:_local1 ?name:_local2 () = 980 | let _msg = Pb.create T.t in 981 | Pb.setf _msg content _local0; 982 | Pb.setf _msg insertion_point _local1; 983 | Pb.setf _msg name _local2; 984 | _msg 985 | end 986 | 987 | module FileDescriptorSet = struct 988 | include Types_.Fields__FileDescriptorSet 989 | 990 | type s = Types_.s_FileDescriptorSet = { 991 | file: Types_.s_FileDescriptorProto list; 992 | } 993 | 994 | let extract = Types_.extract_FileDescriptorSet 995 | 996 | let mk ~file:_local0 () = 997 | let _msg = Pb.create T.t in 998 | Pb.setf _msg file _local0; 999 | _msg 1000 | end 1001 | 1002 | module EnumOptions = struct 1003 | include Types_.Fields__EnumOptions 1004 | 1005 | type s = Types_.s_EnumOptions = { 1006 | uninterpreted_option: Types_.s_UninterpretedOption list; 1007 | deprecated: bool; 1008 | allow_alias: bool option; 1009 | } 1010 | 1011 | let extract = Types_.extract_EnumOptions 1012 | 1013 | let mk ~uninterpreted_option:_local0 ?deprecated:_local1 1014 | ?allow_alias:_local2 () = 1015 | let _msg = Pb.create T.t in 1016 | Pb.setf _msg uninterpreted_option _local0; 1017 | Pb.setf _msg deprecated _local1; 1018 | Pb.setf _msg allow_alias _local2; 1019 | _msg 1020 | end 1021 | 1022 | module MethodDescriptorProto = struct 1023 | include Types_.Fields__MethodDescriptorProto 1024 | 1025 | type s = Types_.s_MethodDescriptorProto = { 1026 | server_streaming: bool; 1027 | client_streaming: bool; 1028 | options: Types_.s_MethodOptions option; 1029 | output_type: string option; 1030 | input_type: string option; 1031 | name: string option; 1032 | } 1033 | 1034 | let extract = Types_.extract_MethodDescriptorProto 1035 | 1036 | let mk ?server_streaming:_local0 ?client_streaming:_local1 ?options:_local2 1037 | ?output_type:_local3 ?input_type:_local4 ?name:_local5 () = 1038 | let _msg = Pb.create T.t in 1039 | Pb.setf _msg server_streaming _local0; 1040 | Pb.setf _msg client_streaming _local1; 1041 | Pb.setf _msg options _local2; 1042 | Pb.setf _msg output_type _local3; 1043 | Pb.setf _msg input_type _local4; 1044 | Pb.setf _msg name _local5; 1045 | _msg 1046 | end 1047 | 1048 | module ServiceDescriptorProto = struct 1049 | include Types_.Fields__ServiceDescriptorProto 1050 | 1051 | type s = Types_.s_ServiceDescriptorProto = { 1052 | options: Types_.s_ServiceOptions option; 1053 | method_: Types_.s_MethodDescriptorProto list; 1054 | name: string option; 1055 | } 1056 | 1057 | let extract = Types_.extract_ServiceDescriptorProto 1058 | 1059 | let mk ?options:_local0 ~method_:_local1 ?name:_local2 () = 1060 | let _msg = Pb.create T.t in 1061 | Pb.setf _msg options _local0; 1062 | Pb.setf _msg method_ _local1; 1063 | Pb.setf _msg name _local2; 1064 | _msg 1065 | end 1066 | 1067 | module ReservedRange = struct 1068 | include Types_.Fields__ReservedRange 1069 | 1070 | type s = Types_.s_ReservedRange = { 1071 | end_: int32 option; 1072 | start: int32 option; 1073 | } 1074 | 1075 | let extract = Types_.extract_ReservedRange 1076 | 1077 | let mk ?end_:_local0 ?start:_local1 () = 1078 | let _msg = Pb.create T.t in 1079 | Pb.setf _msg end_ _local0; 1080 | Pb.setf _msg start _local1; 1081 | _msg 1082 | end 1083 | 1084 | module OneofOptions = struct 1085 | include Types_.Fields__OneofOptions 1086 | 1087 | type s = Types_.s_OneofOptions = { 1088 | uninterpreted_option: Types_.s_UninterpretedOption list; 1089 | } 1090 | 1091 | let extract = Types_.extract_OneofOptions 1092 | 1093 | let mk ~uninterpreted_option:_local0 () = 1094 | let _msg = Pb.create T.t in 1095 | Pb.setf _msg uninterpreted_option _local0; 1096 | _msg 1097 | end 1098 | 1099 | module CodeGeneratorResponse = struct 1100 | include Types_.Fields__CodeGeneratorResponse 1101 | 1102 | type s = Types_.s_CodeGeneratorResponse = { 1103 | file: Types_.s_File list; 1104 | error: string option; 1105 | } 1106 | 1107 | let extract = Types_.extract_CodeGeneratorResponse 1108 | 1109 | let mk ~file:_local0 ?error:_local1 () = 1110 | let _msg = Pb.create T.t in 1111 | Pb.setf _msg file _local0; 1112 | Pb.setf _msg error _local1; 1113 | _msg 1114 | end 1115 | 1116 | module GeneratedCodeInfo = struct 1117 | include Types_.Fields__GeneratedCodeInfo 1118 | 1119 | type s = Types_.s_GeneratedCodeInfo = { 1120 | annotation: Types_.s_Annotation list; 1121 | } 1122 | 1123 | let extract = Types_.extract_GeneratedCodeInfo 1124 | 1125 | let mk ~annotation:_local0 () = 1126 | let _msg = Pb.create T.t in 1127 | Pb.setf _msg annotation _local0; 1128 | _msg 1129 | end 1130 | 1131 | module CodeGeneratorRequest = struct 1132 | include Types_.Fields__CodeGeneratorRequest 1133 | 1134 | type s = Types_.s_CodeGeneratorRequest = { 1135 | compiler_version: Types_.s_Version option; 1136 | proto_file: Types_.s_FileDescriptorProto list; 1137 | parameter: string option; 1138 | file_to_generate: string list; 1139 | } 1140 | 1141 | let extract = Types_.extract_CodeGeneratorRequest 1142 | 1143 | let mk ?compiler_version:_local0 ~proto_file:_local1 ?parameter:_local2 1144 | ~file_to_generate:_local3 () = 1145 | let _msg = Pb.create T.t in 1146 | Pb.setf _msg compiler_version _local0; 1147 | Pb.setf _msg proto_file _local1; 1148 | Pb.setf _msg parameter _local2; 1149 | Pb.setf _msg file_to_generate _local3; 1150 | _msg 1151 | end 1152 | 1153 | module EnumDescriptorProto = struct 1154 | include Types_.Fields__EnumDescriptorProto 1155 | 1156 | type s = Types_.s_EnumDescriptorProto = { 1157 | options: Types_.s_EnumOptions option; 1158 | value: Types_.s_EnumValueDescriptorProto list; 1159 | name: string option; 1160 | } 1161 | 1162 | let extract = Types_.extract_EnumDescriptorProto 1163 | 1164 | let mk ?options:_local0 ~value:_local1 ?name:_local2 () = 1165 | let _msg = Pb.create T.t in 1166 | Pb.setf _msg options _local0; 1167 | Pb.setf _msg value _local1; 1168 | Pb.setf _msg name _local2; 1169 | _msg 1170 | end 1171 | 1172 | module FileOptions = struct 1173 | include Types_.Fields__FileOptions 1174 | 1175 | type s = Types_.s_FileOptions = { 1176 | uninterpreted_option: Types_.s_UninterpretedOption list; 1177 | swift_prefix: string option; 1178 | csharp_namespace: string option; 1179 | objc_class_prefix: string option; 1180 | cc_enable_arenas: bool; 1181 | deprecated: bool; 1182 | py_generic_services: bool; 1183 | java_generic_services: bool; 1184 | cc_generic_services: bool; 1185 | go_package: string option; 1186 | optimize_for: Types_.OptimizeMode.e Pb.enum; 1187 | java_string_check_utf8: bool; 1188 | java_generate_equals_and_hash: bool option; 1189 | java_multiple_files: bool; 1190 | java_outer_classname: string option; 1191 | java_package: string option; 1192 | } 1193 | 1194 | let extract = Types_.extract_FileOptions 1195 | 1196 | let mk ~uninterpreted_option:_local0 ?swift_prefix:_local1 1197 | ?csharp_namespace:_local2 ?objc_class_prefix:_local3 1198 | ?cc_enable_arenas:_local4 ?deprecated:_local5 1199 | ?py_generic_services:_local6 ?java_generic_services:_local7 1200 | ?cc_generic_services:_local8 ?go_package:_local9 ?optimize_for:_local10 1201 | ?java_string_check_utf8:_local11 ?java_generate_equals_and_hash:_local12 1202 | ?java_multiple_files:_local13 ?java_outer_classname:_local14 1203 | ?java_package:_local15 () = 1204 | let _msg = Pb.create T.t in 1205 | Pb.setf _msg uninterpreted_option _local0; 1206 | Pb.setf _msg swift_prefix _local1; 1207 | Pb.setf _msg csharp_namespace _local2; 1208 | Pb.setf _msg objc_class_prefix _local3; 1209 | Pb.setf _msg cc_enable_arenas _local4; 1210 | Pb.setf _msg deprecated _local5; 1211 | Pb.setf _msg py_generic_services _local6; 1212 | Pb.setf _msg java_generic_services _local7; 1213 | Pb.setf _msg cc_generic_services _local8; 1214 | Pb.setf _msg go_package _local9; 1215 | Pb.setf _msg optimize_for _local10; 1216 | Pb.setf _msg java_string_check_utf8 _local11; 1217 | Pb.setf _msg java_generate_equals_and_hash _local12; 1218 | Pb.setf _msg java_multiple_files _local13; 1219 | Pb.setf _msg java_outer_classname _local14; 1220 | Pb.setf _msg java_package _local15; 1221 | _msg 1222 | end 1223 | 1224 | module Annotation = struct 1225 | include Types_.Fields__Annotation 1226 | 1227 | type s = Types_.s_Annotation = { 1228 | end_: int32 option; 1229 | begin_: int32 option; 1230 | source_file: string option; 1231 | path: int32 list; 1232 | } 1233 | 1234 | let extract = Types_.extract_Annotation 1235 | 1236 | let mk ?end_:_local0 ?begin_:_local1 ?source_file:_local2 ~path:_local3 () 1237 | = 1238 | let _msg = Pb.create T.t in 1239 | Pb.setf _msg end_ _local0; 1240 | Pb.setf _msg begin_ _local1; 1241 | Pb.setf _msg source_file _local2; 1242 | Pb.setf _msg path _local3; 1243 | _msg 1244 | end 1245 | 1246 | module OneofDescriptorProto = struct 1247 | include Types_.Fields__OneofDescriptorProto 1248 | 1249 | type s = Types_.s_OneofDescriptorProto = { 1250 | options: Types_.s_OneofOptions option; 1251 | name: string option; 1252 | } 1253 | 1254 | let extract = Types_.extract_OneofDescriptorProto 1255 | 1256 | let mk ?options:_local0 ?name:_local1 () = 1257 | let _msg = Pb.create T.t in 1258 | Pb.setf _msg options _local0; 1259 | Pb.setf _msg name _local1; 1260 | _msg 1261 | end 1262 | 1263 | module EnumValueDescriptorProto = struct 1264 | include Types_.Fields__EnumValueDescriptorProto 1265 | 1266 | type s = Types_.s_EnumValueDescriptorProto = { 1267 | options: Types_.s_EnumValueOptions option; 1268 | number: int32 option; 1269 | name: string option; 1270 | } 1271 | 1272 | let extract = Types_.extract_EnumValueDescriptorProto 1273 | 1274 | let mk ?options:_local0 ?number:_local1 ?name:_local2 () = 1275 | let _msg = Pb.create T.t in 1276 | Pb.setf _msg options _local0; 1277 | Pb.setf _msg number _local1; 1278 | Pb.setf _msg name _local2; 1279 | _msg 1280 | end 1281 | 1282 | module FieldDescriptorProto = struct 1283 | include Types_.Fields__FieldDescriptorProto 1284 | 1285 | type s = Types_.s_FieldDescriptorProto = { 1286 | options: Types_.s_FieldOptions option; 1287 | json_name: string option; 1288 | oneof_index: int32 option; 1289 | default_value: string option; 1290 | extendee: string option; 1291 | type_name: string option; 1292 | type_: Types_.Type.e Pb.enum option; 1293 | label: Types_.Label.e Pb.enum option; 1294 | number: int32 option; 1295 | name: string option; 1296 | } 1297 | 1298 | let extract = Types_.extract_FieldDescriptorProto 1299 | 1300 | let mk ?options:_local0 ?json_name:_local1 ?oneof_index:_local2 1301 | ?default_value:_local3 ?extendee:_local4 ?type_name:_local5 1302 | ?type_:_local6 ?label:_local7 ?number:_local8 ?name:_local9 () = 1303 | let _msg = Pb.create T.t in 1304 | Pb.setf _msg options _local0; 1305 | Pb.setf _msg json_name _local1; 1306 | Pb.setf _msg oneof_index _local2; 1307 | Pb.setf _msg default_value _local3; 1308 | Pb.setf _msg extendee _local4; 1309 | Pb.setf _msg type_name _local5; 1310 | Pb.setf _msg type_ _local6; 1311 | Pb.setf _msg label _local7; 1312 | Pb.setf _msg number _local8; 1313 | Pb.setf _msg name _local9; 1314 | _msg 1315 | end 1316 | 1317 | module SourceCodeInfo = struct 1318 | include Types_.Fields__SourceCodeInfo 1319 | 1320 | type s = Types_.s_SourceCodeInfo = { 1321 | location: Types_.s_Location list; 1322 | } 1323 | 1324 | let extract = Types_.extract_SourceCodeInfo 1325 | 1326 | let mk ~location:_local0 () = 1327 | let _msg = Pb.create T.t in 1328 | Pb.setf _msg location _local0; 1329 | _msg 1330 | end 1331 | 1332 | module FieldOptions = struct 1333 | include Types_.Fields__FieldOptions 1334 | 1335 | type s = Types_.s_FieldOptions = { 1336 | uninterpreted_option: Types_.s_UninterpretedOption list; 1337 | weak: bool; 1338 | deprecated: bool; 1339 | lazy_: bool; 1340 | jstype: Types_.JSType.e Pb.enum; 1341 | packed: bool option; 1342 | ctype: Types_.CType.e Pb.enum; 1343 | } 1344 | 1345 | let extract = Types_.extract_FieldOptions 1346 | 1347 | let mk ~uninterpreted_option:_local0 ?weak:_local1 ?deprecated:_local2 1348 | ?lazy_:_local3 ?jstype:_local4 ?packed:_local5 ?ctype:_local6 () = 1349 | let _msg = Pb.create T.t in 1350 | Pb.setf _msg uninterpreted_option _local0; 1351 | Pb.setf _msg weak _local1; 1352 | Pb.setf _msg deprecated _local2; 1353 | Pb.setf _msg lazy_ _local3; 1354 | Pb.setf _msg jstype _local4; 1355 | Pb.setf _msg packed _local5; 1356 | Pb.setf _msg ctype _local6; 1357 | _msg 1358 | end 1359 | 1360 | module EnumValueOptions = struct 1361 | include Types_.Fields__EnumValueOptions 1362 | 1363 | type s = Types_.s_EnumValueOptions = { 1364 | uninterpreted_option: Types_.s_UninterpretedOption list; 1365 | deprecated: bool; 1366 | } 1367 | 1368 | let extract = Types_.extract_EnumValueOptions 1369 | 1370 | let mk ~uninterpreted_option:_local0 ?deprecated:_local1 () = 1371 | let _msg = Pb.create T.t in 1372 | Pb.setf _msg uninterpreted_option _local0; 1373 | Pb.setf _msg deprecated _local1; 1374 | _msg 1375 | end 1376 | 1377 | module UninterpretedOption = struct 1378 | include Types_.Fields__UninterpretedOption 1379 | 1380 | type s = Types_.s_UninterpretedOption = { 1381 | aggregate_value: string option; 1382 | string_value: Bytes.t option; 1383 | double_value: double option; 1384 | negative_int_value: int64 option; 1385 | positive_int_value: uint64 option; 1386 | identifier_value: string option; 1387 | name: Types_.s_NamePart list; 1388 | } 1389 | 1390 | let extract = Types_.extract_UninterpretedOption 1391 | 1392 | let mk ?aggregate_value:_local0 ?string_value:_local1 ?double_value:_local2 1393 | ?negative_int_value:_local3 ?positive_int_value:_local4 1394 | ?identifier_value:_local5 ~name:_local6 () = 1395 | let _msg = Pb.create T.t in 1396 | Pb.setf _msg aggregate_value _local0; 1397 | Pb.setf _msg string_value _local1; 1398 | Pb.setf _msg double_value _local2; 1399 | Pb.setf _msg negative_int_value _local3; 1400 | Pb.setf _msg positive_int_value _local4; 1401 | Pb.setf _msg identifier_value _local5; 1402 | Pb.setf _msg name _local6; 1403 | _msg 1404 | end 1405 | 1406 | module ExtensionRange = struct 1407 | include Types_.Fields__ExtensionRange 1408 | 1409 | type s = Types_.s_ExtensionRange = { 1410 | end_: int32 option; 1411 | start: int32 option; 1412 | } 1413 | 1414 | let extract = Types_.extract_ExtensionRange 1415 | 1416 | let mk ?end_:_local0 ?start:_local1 () = 1417 | let _msg = Pb.create T.t in 1418 | Pb.setf _msg end_ _local0; 1419 | Pb.setf _msg start _local1; 1420 | _msg 1421 | end 1422 | 1423 | module MessageOptions = struct 1424 | include Types_.Fields__MessageOptions 1425 | 1426 | type s = Types_.s_MessageOptions = { 1427 | uninterpreted_option: Types_.s_UninterpretedOption list; 1428 | map_entry: bool option; 1429 | deprecated: bool; 1430 | no_standard_descriptor_accessor: bool; 1431 | message_set_wire_format: bool; 1432 | } 1433 | 1434 | let extract = Types_.extract_MessageOptions 1435 | 1436 | let mk ~uninterpreted_option:_local0 ?map_entry:_local1 ?deprecated:_local2 1437 | ?no_standard_descriptor_accessor:_local3 1438 | ?message_set_wire_format:_local4 () = 1439 | let _msg = Pb.create T.t in 1440 | Pb.setf _msg uninterpreted_option _local0; 1441 | Pb.setf _msg map_entry _local1; 1442 | Pb.setf _msg deprecated _local2; 1443 | Pb.setf _msg no_standard_descriptor_accessor _local3; 1444 | Pb.setf _msg message_set_wire_format _local4; 1445 | _msg 1446 | end 1447 | 1448 | module MethodOptions = struct 1449 | include Types_.Fields__MethodOptions 1450 | 1451 | type s = Types_.s_MethodOptions = { 1452 | uninterpreted_option: Types_.s_UninterpretedOption list; 1453 | idempotency_level: Types_.IdempotencyLevel.e Pb.enum; 1454 | deprecated: bool; 1455 | } 1456 | 1457 | let extract = Types_.extract_MethodOptions 1458 | 1459 | let mk ~uninterpreted_option:_local0 ?idempotency_level:_local1 1460 | ?deprecated:_local2 () = 1461 | let _msg = Pb.create T.t in 1462 | Pb.setf _msg uninterpreted_option _local0; 1463 | Pb.setf _msg idempotency_level _local1; 1464 | Pb.setf _msg deprecated _local2; 1465 | _msg 1466 | end 1467 | 1468 | module FileDescriptorProto = struct 1469 | include Types_.Fields__FileDescriptorProto 1470 | 1471 | type s = Types_.s_FileDescriptorProto = { 1472 | syntax: string option; 1473 | source_code_info: Types_.s_SourceCodeInfo option; 1474 | options: Types_.s_FileOptions option; 1475 | extension: Types_.s_FieldDescriptorProto list; 1476 | service: Types_.s_ServiceDescriptorProto list; 1477 | enum_type: Types_.s_EnumDescriptorProto list; 1478 | message_type: Types_.s_DescriptorProto list; 1479 | weak_dependency: int32 list; 1480 | public_dependency: int32 list; 1481 | dependency: string list; 1482 | package: string option; 1483 | name: string option; 1484 | } 1485 | 1486 | let extract = Types_.extract_FileDescriptorProto 1487 | 1488 | let mk ?syntax:_local0 ?source_code_info:_local1 ?options:_local2 1489 | ~extension:_local3 ~service:_local4 ~enum_type:_local5 1490 | ~message_type:_local6 ~weak_dependency:_local7 1491 | ~public_dependency:_local8 ~dependency:_local9 ?package:_local10 1492 | ?name:_local11 () = 1493 | let _msg = Pb.create T.t in 1494 | Pb.setf _msg syntax _local0; 1495 | Pb.setf _msg source_code_info _local1; 1496 | Pb.setf _msg options _local2; 1497 | Pb.setf _msg extension _local3; 1498 | Pb.setf _msg service _local4; 1499 | Pb.setf _msg enum_type _local5; 1500 | Pb.setf _msg message_type _local6; 1501 | Pb.setf _msg weak_dependency _local7; 1502 | Pb.setf _msg public_dependency _local8; 1503 | Pb.setf _msg dependency _local9; 1504 | Pb.setf _msg package _local10; 1505 | Pb.setf _msg name _local11; 1506 | _msg 1507 | end 1508 | 1509 | module NamePart = struct 1510 | include Types_.Fields__NamePart 1511 | 1512 | type s = Types_.s_NamePart = { 1513 | is_extension: bool; 1514 | name_part: string; 1515 | } 1516 | 1517 | let extract = Types_.extract_NamePart 1518 | 1519 | let mk ~is_extension:_local0 ~name_part:_local1 () = 1520 | let _msg = Pb.create T.t in 1521 | Pb.setf _msg is_extension _local0; 1522 | Pb.setf _msg name_part _local1; 1523 | _msg 1524 | end 1525 | 1526 | module Version = struct 1527 | include Types_.Fields__Version 1528 | 1529 | type s = Types_.s_Version = { 1530 | suffix: string option; 1531 | patch: int32 option; 1532 | minor: int32 option; 1533 | major: int32 option; 1534 | } 1535 | 1536 | let extract = Types_.extract_Version 1537 | 1538 | let mk ?suffix:_local0 ?patch:_local1 ?minor:_local2 ?major:_local3 () = 1539 | let _msg = Pb.create T.t in 1540 | Pb.setf _msg suffix _local0; 1541 | Pb.setf _msg patch _local1; 1542 | Pb.setf _msg minor _local2; 1543 | Pb.setf _msg major _local3; 1544 | _msg 1545 | end 1546 | 1547 | module OptimizeMode = 1548 | struct 1549 | module T = struct 1550 | type e = Types_.OptimizeMode.e 1551 | let __map = [ 1552 | 1l, `SPEED; 1553 | 2l, `CODE_SIZE; 1554 | 3l, `LITE_RUNTIME; 1555 | ] 1556 | let of_value x = List.assoc x __map 1557 | let to_value x = rassoc x __map 1558 | end 1559 | include Types_.OptimizeMode__constants 1560 | 1561 | end 1562 | 1563 | module Label = 1564 | struct 1565 | module T = struct 1566 | type e = Types_.Label.e 1567 | let __map = [ 1568 | 1l, `LABEL_OPTIONAL; 1569 | 2l, `LABEL_REQUIRED; 1570 | 3l, `LABEL_REPEATED; 1571 | ] 1572 | let of_value x = List.assoc x __map 1573 | let to_value x = rassoc x __map 1574 | end 1575 | include Types_.Label__constants 1576 | 1577 | end 1578 | 1579 | module Type = 1580 | struct 1581 | module T = struct 1582 | type e = Types_.Type.e 1583 | let __map = [ 1584 | 1l, `TYPE_DOUBLE; 1585 | 2l, `TYPE_FLOAT; 1586 | 3l, `TYPE_INT64; 1587 | 4l, `TYPE_UINT64; 1588 | 5l, `TYPE_INT32; 1589 | 6l, `TYPE_FIXED64; 1590 | 7l, `TYPE_FIXED32; 1591 | 8l, `TYPE_BOOL; 1592 | 9l, `TYPE_STRING; 1593 | 10l, `TYPE_GROUP; 1594 | 11l, `TYPE_MESSAGE; 1595 | 12l, `TYPE_BYTES; 1596 | 13l, `TYPE_UINT32; 1597 | 14l, `TYPE_ENUM; 1598 | 15l, `TYPE_SFIXED32; 1599 | 16l, `TYPE_SFIXED64; 1600 | 17l, `TYPE_SINT32; 1601 | 18l, `TYPE_SINT64; 1602 | ] 1603 | let of_value x = List.assoc x __map 1604 | let to_value x = rassoc x __map 1605 | end 1606 | include Types_.Type__constants 1607 | 1608 | end 1609 | 1610 | module JSType = 1611 | struct 1612 | module T = struct 1613 | type e = Types_.JSType.e 1614 | let __map = [ 1615 | 0l, `JS_NORMAL; 1616 | 1l, `JS_STRING; 1617 | 2l, `JS_NUMBER; 1618 | ] 1619 | let of_value x = List.assoc x __map 1620 | let to_value x = rassoc x __map 1621 | end 1622 | include Types_.JSType__constants 1623 | 1624 | end 1625 | 1626 | module IdempotencyLevel = 1627 | struct 1628 | module T = struct 1629 | type e = Types_.IdempotencyLevel.e 1630 | let __map = [ 1631 | 0l, `IDEMPOTENCY_UNKNOWN; 1632 | 1l, `NO_SIDE_EFFECTS; 1633 | 2l, `IDEMPOTENT; 1634 | ] 1635 | let of_value x = List.assoc x __map 1636 | let to_value x = rassoc x __map 1637 | end 1638 | include Types_.IdempotencyLevel__constants 1639 | 1640 | end 1641 | 1642 | module CType = 1643 | struct 1644 | module T = struct 1645 | type e = Types_.CType.e 1646 | let __map = [ 1647 | 0l, `STRING; 1648 | 1l, `CORD; 1649 | 2l, `STRING_PIECE; 1650 | ] 1651 | let of_value x = List.assoc x __map 1652 | let to_value x = rassoc x __map 1653 | end 1654 | include Types_.CType__constants 1655 | 1656 | end 1657 | 1658 | -------------------------------------------------------------------------------- /test/.gitignore: -------------------------------------------------------------------------------- 1 | *.serialized 2 | -------------------------------------------------------------------------------- /test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yallop/ocaml-pb-plugin/696a9570cc6daf63c5f25780dfa108385a6a43b1/test/__init__.py -------------------------------------------------------------------------------- /test/comprehensive.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | 3 | enum Enum { 4 | one = 1; 5 | two = 2; 6 | } 7 | 8 | message Small { 9 | optional string small_s = 100; 10 | optional int64 small_i = 200; 11 | } 12 | 13 | message Comprehensive { 14 | repeated uint32 repeated_uint32 = 1; 15 | required int32 required_int32 = 2; 16 | required Small required_Small = 3; 17 | required double required_double = 4; 18 | optional sfixed32 optional_sfixed32 = 5; 19 | optional fixed32 optional_fixed32 = 6; 20 | repeated bytes repeated_bytes = 7; 21 | repeated bool repeated_bool = 8; 22 | repeated sfixed64 repeated_sfixed64 = 9; 23 | optional bool optional_bool = 10; 24 | required uint32 required_uint32 = 11; 25 | optional double optional_double = 12; 26 | required int64 required_int64 = 13; 27 | required uint64 required_uint64 = 14; 28 | required string required_string = 15; 29 | required bytes required_bytes = 16; 30 | optional bytes optional_bytes = 17; 31 | optional sint64 optional_sint64 = 18; 32 | repeated sint64 repeated_sint64 = 19; 33 | repeated fixed32 repeated_fixed32 = 20; 34 | optional Small optional_Small = 21; 35 | optional int32 optional_int32 = 22; 36 | optional fixed64 optional_fixed64 = 23; 37 | optional Enum optional_enum = 24; 38 | required float required_float = 25; 39 | optional sfixed64 optional_sfixed64 = 26; 40 | required sfixed32 required_sfixed32 = 27; 41 | required bool required_bool = 28; 42 | repeated fixed64 repeated_fixed64 = 29; 43 | optional sint32 optional_sint32 = 30; 44 | repeated int64 repeated_int64 = 31; 45 | required fixed64 required_fixed64 = 32; 46 | repeated Enum repeated_enum = 33; 47 | optional int64 optional_int64 = 34; 48 | repeated float repeated_float = 35; 49 | repeated sint32 repeated_sint32 = 36; 50 | repeated uint64 repeated_uint64 = 37; 51 | repeated Small repeated_Small = 38; 52 | repeated double repeated_double = 39; 53 | repeated string repeated_string = 40; 54 | required sfixed64 required_sfixed64 = 41; 55 | required sint64 required_sint64 = 42; 56 | optional string optional_string = 43; 57 | optional uint32 optional_uint32 = 44; 58 | repeated sfixed32 repeated_sfixed32 = 45; 59 | optional float optional_float = 46; 60 | optional uint64 optional_uint64 = 47; 61 | required Enum required_enum = 48; 62 | required sint32 required_sint32 = 49; 63 | required fixed32 required_fixed32 = 50; 64 | repeated int32 repeated_int32 = 51; 65 | } 66 | -------------------------------------------------------------------------------- /test/dune: -------------------------------------------------------------------------------- 1 | (rule 2 | (targets comprehensive.ml) 3 | (deps comprehensive.proto) 4 | (action (run protoc --plugin=protoc-gen-custom=%{bin:pb-plugin} --custom_out . %{deps}))) 5 | 6 | (rule 7 | (targets comprehensive_pb2.py) 8 | (deps comprehensive.proto) 9 | (action (run protoc --python_out=./ %{deps}))) 10 | 11 | (rule 12 | (targets 13 | comprehensive.python.serialized 14 | small.python.serialized) 15 | (deps (glob_files *.py)) 16 | (action (run python3 ./test_gen.py))) 17 | 18 | (alias 19 | (name runtest) 20 | (deps 21 | (glob_files *.py) 22 | small.ocaml.serialized 23 | comprehensive.ocaml.serialized) 24 | (action (run python3 ./test_read.py))) 25 | 26 | (rule 27 | (deps comprehensive.python.serialized) 28 | (targets comprehensive.ocaml.serialized small.ocaml.serialized) 29 | (action (run ./test.exe))) 30 | 31 | (executable 32 | (name test) 33 | (libraries ounit2 angstrom batteries faraday pb integers)) 34 | -------------------------------------------------------------------------------- /test/test.ml: -------------------------------------------------------------------------------- 1 | (* 2 | * Copyright (c) 2017 Jeremy Yallop . 3 | * 4 | * This file is distributed under the terms of the MIT License. 5 | * See the file LICENSE for details. 6 | *) 7 | 8 | open OUnit2 9 | module C = Comprehensive 10 | 11 | let msg_to_string m = Faraday.serialize_to_string (Pb.write m) 12 | 13 | let read_from_string p s = 14 | match Angstrom.parse_string p s with 15 | | Result.Error _ -> Printf.kprintf failwith "parse failure (%s)" s 16 | | Result.Ok v -> v 17 | 18 | let slurp filename = BatFile.with_file_in filename BatIO.read_all 19 | 20 | let spew s filename = BatFile.with_file_out filename @@ fun fd -> 21 | BatIO.write_string fd s 22 | 23 | 24 | let test_interoperability_small_read _ = 25 | let open C.Small in 26 | let small_string = slurp "small.python.serialized" in 27 | let small = extract 28 | (read_from_string (Pb.read C.Types_.Small.t) small_string) in 29 | begin 30 | assert (small.small_s = Some "abc"); 31 | assert (small.small_i = Some 17L); 32 | end 33 | 34 | 35 | let test_interoperability_comprehensive_read _ = 36 | let open C.Small in 37 | let open C.Comprehensive in 38 | let comprehensive_string = slurp "comprehensive.python.serialized" in 39 | let c = extract (read_from_string (Pb.read C.Types_.Comprehensive.t) 40 | comprehensive_string) in 41 | begin 42 | let u32 = Unsigned.UInt32.of_int 43 | and u64 = Unsigned.UInt64.of_int 44 | and bytes = Bytes.of_string in 45 | assert (c.repeated_uint32 = [u32 1; u32 2]); 46 | assert (c.required_int32 = 3_l); 47 | let s = c.required_Small in 48 | assert (s.small_s = Some "abc"); 49 | assert (s.small_i = Some 17L); 50 | assert (c.required_double = 4.1); 51 | assert (c.optional_sfixed32 = Some 5_l); 52 | assert (c.optional_fixed32 = Some (u32 6)); 53 | assert (c.repeated_bytes = [bytes "def"; bytes "gh"]); 54 | assert (c.repeated_bool = [false; true]); 55 | assert (c.repeated_sfixed64 = [7_L; 8_L; 9_L]); 56 | assert (c.optional_bool = Some true); 57 | assert (c.required_uint32 = u32 10); 58 | assert (c.optional_double = Some 11.2); 59 | assert (c.required_int64 = 12_L); 60 | assert (c.required_uint64 = u64 13); 61 | assert (c.required_string = "rstuvw"); 62 | assert (c.required_bytes = bytes "lmnopq"); 63 | assert (c.optional_bytes = Some (bytes "rstuv")); 64 | assert (c.optional_sint64 = Some 14_L); 65 | assert (c.repeated_sint64 = [-15_L; 16_L; 17_L]); 66 | assert (c.repeated_fixed32 = [u32 18; u32 19; u32 20; u32 21]); 67 | let () = match c.optional_Small with 68 | None -> assert false 69 | | Some s -> 70 | assert (s.small_s = Some "abc"); 71 | assert (s.small_i = Some 17L); 72 | in 73 | assert (c.optional_int32 = Some 22_l); 74 | assert (c.optional_fixed64 = Some (u64 23)); 75 | assert (c.optional_enum = Some C.Enum.one); 76 | assert (c.required_float = 24.5); 77 | assert (c.optional_sfixed64 = Some 25_L); 78 | assert (c.required_sfixed32 = 26_l); 79 | assert (c.required_bool = true); 80 | assert (c.repeated_fixed64 = [u64 27; u64 28; u64 29; u64 30; u64 31]); 81 | assert (c.optional_sint32 = Some 32_l); 82 | assert (c.repeated_int64 = [33_L; 34_L; 35_L; 36_L; 37_L; 38_L; 39_L]); 83 | assert (c.required_fixed64 = u64 40); 84 | assert (c.repeated_enum = [C.Enum.one; C.Enum.two]); 85 | assert (c.optional_int64 = Some 41_L); 86 | assert (c.repeated_float = [42.0]); 87 | assert (c.repeated_sint32 = [44_l; 45_l; 46_l; 47_l; 48_l; 49_l]); 88 | assert (c.repeated_uint64 = [u64 50; u64 51; u64 52; u64 53; u64 54; u64 55]); 89 | let () = match c.repeated_Small with 90 | [s1; s2] -> 91 | assert (s2.small_s = None); 92 | assert (s2.small_i = Some 100L); 93 | assert (s1.small_s = Some "abc"); 94 | assert (s1.small_i = Some 17L); 95 | | _ -> assert false 96 | in 97 | assert (c.repeated_double = [56.3; 57.4; 58.0; 59.1]); 98 | assert (c.repeated_string = ["w"; ""; "yz"]); 99 | assert (c.required_sfixed64 = 60_L); 100 | assert (c.required_sint64 = 61_L); 101 | assert (c.optional_string = Some "A3"); 102 | assert (c.optional_uint32 = Some (u32 62)); 103 | assert (c.repeated_sfixed32 = [63_l; 64_l; 65_l; 66_l; 67_l; 68_l]); 104 | assert (c.optional_float = Some 69.0); 105 | assert (c.optional_uint64 = Some (u64 70)); 106 | assert (c.required_enum = C.Enum.two); 107 | assert (c.required_sint32 = 71_l); 108 | assert (c.required_fixed32 = u32 72); 109 | assert (c.repeated_int32 = [73_l; 74_l; 75_l; 76_l; 77_l; 78_l]); 110 | end 111 | 112 | 113 | let test_interoperability_small_write _ = 114 | let small = C.Small.mk ~small_s:"abc" ~small_i:17_L () in 115 | spew (msg_to_string small) "small.ocaml.serialized" 116 | 117 | 118 | let test_interoperability_comprehensive_write _ = 119 | let u32 = Unsigned.UInt32.of_int 120 | and u64 = Unsigned.UInt64.of_int 121 | and bytes = Bytes.of_string in 122 | let s = C.Small.mk ~small_s:"abc" ~small_i:17_L () in 123 | let s2 = C.Small.mk ~small_i:100_L () in 124 | let c = C.Comprehensive.mk 125 | ~repeated_uint32:[u32 1; u32 2] 126 | ~required_int32:3_l 127 | ~required_Small:s 128 | ~required_double:4.1 129 | ~optional_sfixed32:5_l 130 | ~optional_fixed32:(u32 6) 131 | ~repeated_bytes:[bytes "def"; bytes "gh"] 132 | ~repeated_bool:[false; true] 133 | ~repeated_sfixed64:[7_L; 8_L; 9_L] 134 | ~optional_bool:true 135 | ~required_uint32:(u32 10) 136 | ~optional_double:11.2 137 | ~required_int64:12_L 138 | ~required_uint64:(u64 13) 139 | ~required_string:"rstuvw" 140 | ~required_bytes:(bytes "lmnopq") 141 | ~optional_bytes:(bytes "rstuv") 142 | ~optional_sint64:14_L 143 | ~repeated_sint64:[-15_L; 16_L; 17_L] 144 | ~repeated_fixed32:[u32 18; u32 19; u32 20; u32 21] 145 | ~optional_Small:s 146 | ~optional_int32:22_l 147 | ~optional_fixed64:(u64 23) 148 | ~optional_enum:C.Enum.one 149 | ~required_float:24.5 150 | ~optional_sfixed64:25_L 151 | ~required_sfixed32:26_l 152 | ~required_bool:true 153 | ~repeated_fixed64:[u64 27; u64 28; u64 29; u64 30; u64 31] 154 | ~optional_sint32:32_l 155 | ~repeated_int64:[33_L; 34_L; 35_L; 36_L; 37_L; 38_L; 100000000039_L] 156 | ~required_fixed64:(u64 40) 157 | ~repeated_enum:[C.Enum.one; C.Enum.two] 158 | ~optional_int64:41_L 159 | ~repeated_float:[42.0] 160 | ~repeated_sint32:[44_l; 45_l; 46_l; 47_l; 48_l; 49_l] 161 | ~repeated_uint64:[u64 50; u64 51; u64 52; u64 53; u64 54; u64 55] 162 | ~repeated_Small:[s; s2] 163 | ~repeated_double:[56.3; 57.4; 58.0; 59.1] 164 | ~repeated_string:["w"; ""; "yz"] 165 | ~required_sfixed64:60_L 166 | ~required_sint64:61_L 167 | ~optional_string:"A3" 168 | ~optional_uint32:(u32 62) 169 | ~repeated_sfixed32:[63_l; 64_l; 65_l; 66_l; 67_l; 68_l] 170 | ~optional_float:69.0 171 | ~optional_uint64:(u64 70) 172 | ~required_enum:C.Enum.two 173 | ~required_sint32:71_l 174 | ~required_fixed32:(u32 72) 175 | ~repeated_int32:[73_l; 74_l; 75_l; 76_l; 77_l; 78_l] 176 | () 177 | in 178 | spew (msg_to_string c) "comprehensive.ocaml.serialized" 179 | 180 | 181 | let suite = "Protobuf wire format tests" >::: 182 | ["test interoperability (small read)" 183 | >:: test_interoperability_small_read; 184 | 185 | "test interoperability (comprehensive read)" 186 | >:: test_interoperability_comprehensive_read; 187 | 188 | "test interoperability (small write)" 189 | >:: test_interoperability_small_write; 190 | 191 | "test interoperability (comprehensive write)" 192 | >:: test_interoperability_comprehensive_write; 193 | ] 194 | 195 | 196 | let _ = 197 | run_test_tt_main suite 198 | -------------------------------------------------------------------------------- /test/test_gen.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import comprehensive_pb2 4 | test_pb2 = comprehensive_pb2 5 | 6 | e1 = test_pb2.Enum.Value('one') 7 | e2 = test_pb2.Enum.Value('two') 8 | 9 | s1 = test_pb2.Small() 10 | s1.small_s = 'abc' 11 | s1.small_i = 17 12 | 13 | s2 = test_pb2.Small() 14 | s2.small_i = 100 15 | 16 | c = test_pb2.Comprehensive() 17 | c.repeated_uint32.extend([1,2]) 18 | c.required_int32 = 3 19 | c.required_Small.CopyFrom(s1) 20 | c.required_double = 4.1 21 | c.optional_sfixed32 = 5 22 | c.optional_fixed32 = 6 23 | c.repeated_bytes.extend([b'def', b'gh']) 24 | c.repeated_bool.extend([False, True]) 25 | c.repeated_sfixed64.extend([7,8,9]) 26 | c.optional_bool = True 27 | c.required_uint32 = 10 28 | c.optional_double = 11.2 29 | c.required_int64 = 12 30 | c.required_uint64 = 13 31 | c.required_string = 'rstuvw' 32 | c.required_bytes = b'lmnopq' 33 | c.optional_bytes = b'rstuv' 34 | c.optional_sint64 = 14 35 | c.repeated_sint64.extend([-15,16,17]) 36 | c.repeated_fixed32.extend([18,19,20,21]) 37 | c.optional_Small.CopyFrom(s1) 38 | c.optional_int32 = 22 39 | c.optional_fixed64 = 23 40 | c.optional_enum = e1 41 | c.required_float = 24.5 42 | c.optional_sfixed64 = 25 43 | c.required_sfixed32 = 26 44 | c.required_bool = True 45 | c.repeated_fixed64.extend([27,28,29,30,31]) 46 | c.optional_sint32 = 32 47 | c.repeated_int64.extend([33,34,35,36,37,38,39]) 48 | c.required_fixed64 = 40 49 | c.repeated_enum.extend([e1, e2]) 50 | c.optional_int64 = 41 51 | c.repeated_float.extend([42.0]) 52 | c.repeated_sint32.extend([44, 45, 46, 47, 48, 49]) 53 | c.repeated_uint64.extend([50, 51, 52, 53, 54, 55]) 54 | c.repeated_Small.extend([s1, s2]) 55 | c.repeated_double.extend([56.3, 57.4, 58.0, 59.1]) 56 | c.repeated_string.extend(['w', '', 'yz']) 57 | c.required_sfixed64 = 60 58 | c.required_sint64 = 61 59 | c.optional_string = 'A3' 60 | c.optional_uint32 = 62 61 | c.repeated_sfixed32.extend([63, 64, 65, 66, 67, 68]) 62 | c.optional_float = 69.0 63 | c.optional_uint64 = 70 64 | c.required_enum = e2 65 | c.required_sint32 = 71 66 | c.required_fixed32 = 72 67 | c.repeated_int32.extend([73, 74, 75, 76, 77, 78]) 68 | 69 | def main(): 70 | print('generating comprehensive.serialized') 71 | with open('comprehensive.python.serialized', 'wb') as fd: 72 | fd.write(c.SerializeToString()) 73 | 74 | print('generating small.serialized') 75 | with open('small.python.serialized', 'wb') as fd: 76 | fd.write(s1.SerializeToString()) 77 | 78 | if __name__ == '__main__': 79 | main() 80 | -------------------------------------------------------------------------------- /test/test_read.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import comprehensive_pb2 4 | test_pb2 = comprehensive_pb2 5 | 6 | def from_bytes(msg, filename): 7 | with open(filename, 'rb') as fd: 8 | return msg.FromString(fd.read()) 9 | 10 | def main(): 11 | small = from_bytes(test_pb2.Small, 'small.ocaml.serialized') 12 | assert small.small_s == 'abc' 13 | assert small.small_i == 17 14 | 15 | if True: return 16 | 17 | c = from_bytes(test_pb2.Comprehensive, 'comprehensive.ocaml.serialized') 18 | assert list(c.repeated_uint32) == [1,2] 19 | assert c.required_int32 == 3 20 | s1 = c.required_Small 21 | assert s1.small_s == 'abc' 22 | assert s1.small_i == 17 23 | assert c.required_double == 4.1 24 | assert c.optional_sfixed32 == 5 25 | assert c.optional_fixed32 == 6 26 | assert list(c.repeated_bytes) == ['def', 'gh'] 27 | assert list(c.repeated_bool) == [False, True] 28 | assert list(c.repeated_sfixed64) == [7,8,9] 29 | assert c.optional_bool == True 30 | assert c.required_uint32 == 10 31 | assert c.optional_double == 11.2 32 | assert c.required_int64 == 12 33 | assert c.required_uint64 == 13 34 | assert c.required_string == 'rstuvw' 35 | assert c.required_bytes == 'lmnopq' 36 | assert c.optional_bytes == 'rstuv' 37 | assert c.optional_sint64 == 14 38 | assert list(c.repeated_sint64) == [-15,16,17] 39 | assert list(c.repeated_fixed32) == [18,19,20,21] 40 | s1 = c.optional_Small 41 | assert s1.small_s == 'abc' 42 | assert s1.small_i == 17 43 | assert c.optional_int32 == 22 44 | assert c.optional_fixed64 == 23 45 | e1 = c.optional_enum 46 | assert e1 == test_pb2.Enum.Value('one') 47 | assert c.required_float == 24.5 48 | assert c.optional_sfixed64 == 25 49 | assert c.required_sfixed32 == 26 50 | assert c.required_bool == True 51 | assert list(c.repeated_fixed64) == [27,28,29,30,31] 52 | assert c.optional_sint32 == 32 53 | assert list(c.repeated_int64) == [33,34,35,36,37,38,100000000039] 54 | assert c.required_fixed64 == 40 55 | e2 = test_pb2.Enum.Value('two') 56 | assert list(c.repeated_enum) == [e1, e2] 57 | assert c.optional_int64 == 41 58 | assert list(c.repeated_float) == [42.0] 59 | assert list(c.repeated_sint32) == [44, 45, 46, 47, 48, 49] 60 | assert list(c.repeated_uint64) == [50, 51, 52, 53, 54, 55] 61 | [s1, s2] = c.repeated_Small 62 | assert s1.small_s == 'abc' 63 | assert s1.small_i == 17 64 | assert s2.small_s == '' 65 | assert s2.small_i == 100 66 | assert list(c.repeated_double) == [56.3, 57.4, 58.0, 59.1] 67 | assert list(c.repeated_string) == ['w', '', 'yz'] 68 | assert c.required_sfixed64 == 60 69 | assert c.required_sint64 == 61 70 | assert c.optional_string == 'A3' 71 | assert c.optional_uint32 == 62 72 | assert list(c.repeated_sfixed32) == [63, 64, 65, 66, 67, 68] 73 | assert c.optional_float == 69.0 74 | assert c.optional_uint64 == 70 75 | assert c.required_enum == e2 76 | assert c.required_sint32 == 71 77 | assert c.required_fixed32 == 72 78 | assert list(c.repeated_int32) == [73, 74, 75, 76, 77, 78] 79 | 80 | 81 | if __name__ == '__main__': 82 | main() 83 | --------------------------------------------------------------------------------