mirror of https://github.com/apache/activemq.git
[AMQ-9485] Host activemq-protobuf modules for modernization
This commit is contained in:
parent
6e6caf7c60
commit
f9cf7a3789
|
@ -0,0 +1,80 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.apache.activemq</groupId>
|
||||
<artifactId>activemq-parent</artifactId>
|
||||
<version>6.1.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<groupId>org.apache.activemq.protobuf</groupId>
|
||||
<artifactId>activemq-protobuf-test</artifactId>
|
||||
|
||||
<packaging>jar</packaging>
|
||||
<name>ActiveMQ :: Protocol Buffers Tests</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.activemq.protobuf</groupId>
|
||||
<artifactId>activemq-protobuf</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.activemq.protobuf</groupId>
|
||||
<artifactId>activemq-protobuf</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>**/*Test.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.activemq.protobuf</groupId>
|
||||
<artifactId>activemq-protobuf</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,40 @@
|
|||
//
|
||||
// Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
// contributor license agreements. See the NOTICE file distributed with
|
||||
// this work for additional information regarding copyright ownership.
|
||||
// The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
// (the "License"); you may not use this file except in compliance with
|
||||
// the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package org.apache.activemq.protobuf;
|
||||
option java_outer_classname = "DeferredUnmarshal";
|
||||
option deferred_decode = true;
|
||||
|
||||
message Foo {
|
||||
|
||||
optional int32 field1 = 1;
|
||||
optional int64 field2 = 2;
|
||||
|
||||
}
|
||||
|
||||
|
||||
message Bar {
|
||||
option base_type=Foo;
|
||||
|
||||
// These are the Foo fields.
|
||||
optional int32 field1 = 1;
|
||||
optional int64 field2 = 2;
|
||||
|
||||
optional Foo field3 = 3;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc.
|
||||
// http://code.google.com/p/protobuf/
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Author: kenton@google.com (Kenton Varda)
|
||||
//
|
||||
// A proto file which tests the java_multiple_files option.
|
||||
|
||||
|
||||
import "unittest.proto";
|
||||
|
||||
package protobuf_unittest;
|
||||
|
||||
option java_multiple_files = true;
|
||||
option java_outer_classname = "MultipleFilesTestProto";
|
||||
|
||||
message MessageWithNoOuter {
|
||||
message NestedMessage {
|
||||
optional int32 i = 1;
|
||||
}
|
||||
enum NestedEnum {
|
||||
BAZ = 3;
|
||||
}
|
||||
optional NestedMessage nested = 1;
|
||||
repeated TestAllTypes foreign = 2;
|
||||
optional NestedEnum nested_enum = 3;
|
||||
optional EnumWithNoOuter foreign_enum = 4;
|
||||
}
|
||||
|
||||
enum EnumWithNoOuter {
|
||||
FOO = 1;
|
||||
BAR = 2;
|
||||
}
|
||||
|
||||
service ServiceWithNoOuter {
|
||||
rpc Foo(MessageWithNoOuter) returns(TestAllTypes);
|
||||
}
|
||||
|
||||
extend TestAllExtensions {
|
||||
optional int32 extension_with_outer = 1234567;
|
||||
}
|
|
@ -0,0 +1,452 @@
|
|||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc.
|
||||
// http://code.google.com/p/protobuf/
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Author: kenton@google.com (Kenton Varda)
|
||||
// Based on original Protocol Buffers design by
|
||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||
//
|
||||
// A proto file we will use for unit testing.
|
||||
|
||||
|
||||
import "unittest_import.proto";
|
||||
|
||||
// We don't put this in a package within proto2 because we need to make sure
|
||||
// that the generated code doesn't depend on being in the proto2 namespace.
|
||||
// In test_util.h we do "using namespace unittest = protobuf_unittest".
|
||||
package protobuf_unittest;
|
||||
|
||||
// Protos optimized for SPEED use a strict superset of the generated code
|
||||
// of equivalent ones optimized for CODE_SIZE, so we should optimize all our
|
||||
// tests for speed unless explicitly testing code size optimization.
|
||||
option optimize_for = SPEED;
|
||||
|
||||
option java_outer_classname = "UnittestProto";
|
||||
|
||||
// This proto includes every type of field in both singular and repeated
|
||||
// forms.
|
||||
message TestAllTypes {
|
||||
message NestedMessage {
|
||||
// The field name "b" fails to compile in proto1 because it conflicts with
|
||||
// a local variable named "b" in one of the generated methods. Doh.
|
||||
// This file needs to compile in proto1 to test backwards-compatibility.
|
||||
optional int32 bb = 1;
|
||||
}
|
||||
|
||||
enum NestedEnum {
|
||||
FOO = 1;
|
||||
BAR = 2;
|
||||
BAZ = 3;
|
||||
}
|
||||
|
||||
// Singular
|
||||
optional int32 optional_int32 = 1;
|
||||
optional int64 optional_int64 = 2;
|
||||
optional uint32 optional_uint32 = 3;
|
||||
optional uint64 optional_uint64 = 4;
|
||||
optional sint32 optional_sint32 = 5;
|
||||
optional sint64 optional_sint64 = 6;
|
||||
optional fixed32 optional_fixed32 = 7;
|
||||
optional fixed64 optional_fixed64 = 8;
|
||||
optional sfixed32 optional_sfixed32 = 9;
|
||||
optional sfixed64 optional_sfixed64 = 10;
|
||||
optional float optional_float = 11;
|
||||
optional double optional_double = 12;
|
||||
optional bool optional_bool = 13;
|
||||
optional string optional_string = 14;
|
||||
optional bytes optional_bytes = 15;
|
||||
|
||||
optional group OptionalGroup = 16 {
|
||||
optional int32 a = 17;
|
||||
}
|
||||
|
||||
optional NestedMessage optional_nested_message = 18;
|
||||
optional ForeignMessage optional_foreign_message = 19;
|
||||
optional protobuf_unittest_import.ImportMessage optional_import_message = 20;
|
||||
|
||||
optional NestedEnum optional_nested_enum = 21;
|
||||
optional ForeignEnum optional_foreign_enum = 22;
|
||||
optional protobuf_unittest_import.ImportEnum optional_import_enum = 23;
|
||||
|
||||
optional string optional_string_piece = 24 [ctype=STRING_PIECE];
|
||||
optional string optional_cord = 25 [ctype=CORD];
|
||||
|
||||
// Repeated
|
||||
repeated int32 repeated_int32 = 31;
|
||||
repeated int64 repeated_int64 = 32;
|
||||
repeated uint32 repeated_uint32 = 33;
|
||||
repeated uint64 repeated_uint64 = 34;
|
||||
repeated sint32 repeated_sint32 = 35;
|
||||
repeated sint64 repeated_sint64 = 36;
|
||||
repeated fixed32 repeated_fixed32 = 37;
|
||||
repeated fixed64 repeated_fixed64 = 38;
|
||||
repeated sfixed32 repeated_sfixed32 = 39;
|
||||
repeated sfixed64 repeated_sfixed64 = 40;
|
||||
repeated float repeated_float = 41;
|
||||
repeated double repeated_double = 42;
|
||||
repeated bool repeated_bool = 43;
|
||||
repeated string repeated_string = 44;
|
||||
repeated bytes repeated_bytes = 45;
|
||||
|
||||
repeated group RepeatedGroup = 46 {
|
||||
optional int32 a = 47;
|
||||
}
|
||||
|
||||
repeated NestedMessage repeated_nested_message = 48;
|
||||
repeated ForeignMessage repeated_foreign_message = 49;
|
||||
repeated protobuf_unittest_import.ImportMessage repeated_import_message = 50;
|
||||
|
||||
repeated NestedEnum repeated_nested_enum = 51;
|
||||
repeated ForeignEnum repeated_foreign_enum = 52;
|
||||
repeated protobuf_unittest_import.ImportEnum repeated_import_enum = 53;
|
||||
|
||||
repeated string repeated_string_piece = 54 [ctype=STRING_PIECE];
|
||||
repeated string repeated_cord = 55 [ctype=CORD];
|
||||
|
||||
// Singular with defaults
|
||||
optional int32 default_int32 = 61 [default = 41 ];
|
||||
optional int64 default_int64 = 62 [default = 42 ];
|
||||
optional uint32 default_uint32 = 63 [default = 43 ];
|
||||
optional uint64 default_uint64 = 64 [default = 44 ];
|
||||
optional sint32 default_sint32 = 65 [default = -45 ];
|
||||
optional sint64 default_sint64 = 66 [default = 46 ];
|
||||
optional fixed32 default_fixed32 = 67 [default = 47 ];
|
||||
optional fixed64 default_fixed64 = 68 [default = 48 ];
|
||||
optional sfixed32 default_sfixed32 = 69 [default = 49 ];
|
||||
optional sfixed64 default_sfixed64 = 70 [default = -50 ];
|
||||
optional float default_float = 71 [default = 51.5 ];
|
||||
optional double default_double = 72 [default = 52e3 ];
|
||||
optional bool default_bool = 73 [default = true ];
|
||||
optional string default_string = 74 [default = "hello"];
|
||||
optional bytes default_bytes = 75 [default = "world"];
|
||||
|
||||
optional NestedEnum default_nested_enum = 81 [default = BAR ];
|
||||
optional ForeignEnum default_foreign_enum = 82 [default = FOREIGN_BAR];
|
||||
optional protobuf_unittest_import.ImportEnum
|
||||
default_import_enum = 83 [default = IMPORT_BAR];
|
||||
|
||||
optional string default_string_piece = 84 [ctype=STRING_PIECE,default="abc"];
|
||||
optional string default_cord = 85 [ctype=CORD,default="123"];
|
||||
}
|
||||
|
||||
// Define these after TestAllTypes to make sure the compiler can handle
|
||||
// that.
|
||||
message ForeignMessage {
|
||||
optional int32 c = 1;
|
||||
}
|
||||
|
||||
enum ForeignEnum {
|
||||
FOREIGN_FOO = 4;
|
||||
FOREIGN_BAR = 5;
|
||||
FOREIGN_BAZ = 6;
|
||||
}
|
||||
|
||||
message TestAllExtensions {
|
||||
extensions 1 to max;
|
||||
}
|
||||
|
||||
extend TestAllExtensions {
|
||||
// Singular
|
||||
optional int32 optional_int32_extension = 1;
|
||||
optional int64 optional_int64_extension = 2;
|
||||
optional uint32 optional_uint32_extension = 3;
|
||||
optional uint64 optional_uint64_extension = 4;
|
||||
optional sint32 optional_sint32_extension = 5;
|
||||
optional sint64 optional_sint64_extension = 6;
|
||||
optional fixed32 optional_fixed32_extension = 7;
|
||||
optional fixed64 optional_fixed64_extension = 8;
|
||||
optional sfixed32 optional_sfixed32_extension = 9;
|
||||
optional sfixed64 optional_sfixed64_extension = 10;
|
||||
optional float optional_float_extension = 11;
|
||||
optional double optional_double_extension = 12;
|
||||
optional bool optional_bool_extension = 13;
|
||||
optional string optional_string_extension = 14;
|
||||
optional bytes optional_bytes_extension = 15;
|
||||
|
||||
optional group OptionalGroup_extension = 16 {
|
||||
optional int32 a = 17;
|
||||
}
|
||||
|
||||
optional TestAllTypes.NestedMessage optional_nested_message_extension = 18;
|
||||
optional ForeignMessage optional_foreign_message_extension = 19;
|
||||
optional protobuf_unittest_import.ImportMessage
|
||||
optional_import_message_extension = 20;
|
||||
|
||||
optional TestAllTypes.NestedEnum optional_nested_enum_extension = 21;
|
||||
optional ForeignEnum optional_foreign_enum_extension = 22;
|
||||
optional protobuf_unittest_import.ImportEnum
|
||||
optional_import_enum_extension = 23;
|
||||
|
||||
optional string optional_string_piece_extension = 24 [ctype=STRING_PIECE];
|
||||
optional string optional_cord_extension = 25 [ctype=CORD];
|
||||
|
||||
// Repeated
|
||||
repeated int32 repeated_int32_extension = 31;
|
||||
repeated int64 repeated_int64_extension = 32;
|
||||
repeated uint32 repeated_uint32_extension = 33;
|
||||
repeated uint64 repeated_uint64_extension = 34;
|
||||
repeated sint32 repeated_sint32_extension = 35;
|
||||
repeated sint64 repeated_sint64_extension = 36;
|
||||
repeated fixed32 repeated_fixed32_extension = 37;
|
||||
repeated fixed64 repeated_fixed64_extension = 38;
|
||||
repeated sfixed32 repeated_sfixed32_extension = 39;
|
||||
repeated sfixed64 repeated_sfixed64_extension = 40;
|
||||
repeated float repeated_float_extension = 41;
|
||||
repeated double repeated_double_extension = 42;
|
||||
repeated bool repeated_bool_extension = 43;
|
||||
repeated string repeated_string_extension = 44;
|
||||
repeated bytes repeated_bytes_extension = 45;
|
||||
|
||||
repeated group RepeatedGroup_extension = 46 {
|
||||
optional int32 a = 47;
|
||||
}
|
||||
|
||||
repeated TestAllTypes.NestedMessage repeated_nested_message_extension = 48;
|
||||
repeated ForeignMessage repeated_foreign_message_extension = 49;
|
||||
repeated protobuf_unittest_import.ImportMessage
|
||||
repeated_import_message_extension = 50;
|
||||
|
||||
repeated TestAllTypes.NestedEnum repeated_nested_enum_extension = 51;
|
||||
repeated ForeignEnum repeated_foreign_enum_extension = 52;
|
||||
repeated protobuf_unittest_import.ImportEnum
|
||||
repeated_import_enum_extension = 53;
|
||||
|
||||
repeated string repeated_string_piece_extension = 54 [ctype=STRING_PIECE];
|
||||
repeated string repeated_cord_extension = 55 [ctype=CORD];
|
||||
|
||||
// Singular with defaults
|
||||
optional int32 default_int32_extension = 61 [default = 41 ];
|
||||
optional int64 default_int64_extension = 62 [default = 42 ];
|
||||
optional uint32 default_uint32_extension = 63 [default = 43 ];
|
||||
optional uint64 default_uint64_extension = 64 [default = 44 ];
|
||||
optional sint32 default_sint32_extension = 65 [default = -45 ];
|
||||
optional sint64 default_sint64_extension = 66 [default = 46 ];
|
||||
optional fixed32 default_fixed32_extension = 67 [default = 47 ];
|
||||
optional fixed64 default_fixed64_extension = 68 [default = 48 ];
|
||||
optional sfixed32 default_sfixed32_extension = 69 [default = 49 ];
|
||||
optional sfixed64 default_sfixed64_extension = 70 [default = -50 ];
|
||||
optional float default_float_extension = 71 [default = 51.5 ];
|
||||
optional double default_double_extension = 72 [default = 52e3 ];
|
||||
optional bool default_bool_extension = 73 [default = true ];
|
||||
optional string default_string_extension = 74 [default = "hello"];
|
||||
optional bytes default_bytes_extension = 75 [default = "world"];
|
||||
|
||||
optional TestAllTypes.NestedEnum
|
||||
default_nested_enum_extension = 81 [default = BAR];
|
||||
optional ForeignEnum
|
||||
default_foreign_enum_extension = 82 [default = FOREIGN_BAR];
|
||||
optional protobuf_unittest_import.ImportEnum
|
||||
default_import_enum_extension = 83 [default = IMPORT_BAR];
|
||||
|
||||
optional string default_string_piece_extension = 84 [ctype=STRING_PIECE,
|
||||
default="abc"];
|
||||
optional string default_cord_extension = 85 [ctype=CORD, default="123"];
|
||||
}
|
||||
|
||||
// We have separate messages for testing required fields because it's
|
||||
// annoying to have to fill in required fields in TestProto in order to
|
||||
// do anything with it. Note that we don't need to test every type of
|
||||
// required filed because the code output is basically identical to
|
||||
// optional fields for all types.
|
||||
message TestRequired {
|
||||
required int32 a = 1;
|
||||
optional int32 dummy2 = 2;
|
||||
required int32 b = 3;
|
||||
|
||||
extend TestAllExtensions {
|
||||
optional TestRequired single = 1000;
|
||||
repeated TestRequired multi = 1001;
|
||||
}
|
||||
|
||||
// Pad the field count to 32 so that we can test that IsInitialized()
|
||||
// properly checks multiple elements of has_bits_.
|
||||
optional int32 dummy4 = 4;
|
||||
optional int32 dummy5 = 5;
|
||||
optional int32 dummy6 = 6;
|
||||
optional int32 dummy7 = 7;
|
||||
optional int32 dummy8 = 8;
|
||||
optional int32 dummy9 = 9;
|
||||
optional int32 dummy10 = 10;
|
||||
optional int32 dummy11 = 11;
|
||||
optional int32 dummy12 = 12;
|
||||
optional int32 dummy13 = 13;
|
||||
optional int32 dummy14 = 14;
|
||||
optional int32 dummy15 = 15;
|
||||
optional int32 dummy16 = 16;
|
||||
optional int32 dummy17 = 17;
|
||||
optional int32 dummy18 = 18;
|
||||
optional int32 dummy19 = 19;
|
||||
optional int32 dummy20 = 20;
|
||||
optional int32 dummy21 = 21;
|
||||
optional int32 dummy22 = 22;
|
||||
optional int32 dummy23 = 23;
|
||||
optional int32 dummy24 = 24;
|
||||
optional int32 dummy25 = 25;
|
||||
optional int32 dummy26 = 26;
|
||||
optional int32 dummy27 = 27;
|
||||
optional int32 dummy28 = 28;
|
||||
optional int32 dummy29 = 29;
|
||||
optional int32 dummy30 = 30;
|
||||
optional int32 dummy31 = 31;
|
||||
optional int32 dummy32 = 32;
|
||||
|
||||
required int32 c = 33;
|
||||
}
|
||||
|
||||
message TestRequiredForeign {
|
||||
optional TestRequired optional_message = 1;
|
||||
repeated TestRequired repeated_message = 2;
|
||||
optional int32 dummy = 3;
|
||||
}
|
||||
|
||||
// Test that we can use NestedMessage from outside TestAllTypes.
|
||||
message TestForeignNested {
|
||||
optional TestAllTypes.NestedMessage foreign_nested = 1;
|
||||
}
|
||||
|
||||
// TestEmptyMessage is used to test unknown field support.
|
||||
message TestEmptyMessage {
|
||||
}
|
||||
|
||||
// Like above, but declare all field numbers as potential extensions. No
|
||||
// actual extensions should ever be defined for this type.
|
||||
message TestEmptyMessageWithExtensions {
|
||||
extensions 1 to max;
|
||||
}
|
||||
|
||||
// Test that really large tag numbers don't break anything.
|
||||
message TestReallyLargeTagNumber {
|
||||
// The largest possible tag number is 2^28 - 1, since the wire format uses
|
||||
// three bits to communicate wire type.
|
||||
optional int32 a = 1;
|
||||
optional int32 bb = 268435455;
|
||||
}
|
||||
|
||||
message TestRecursiveMessage {
|
||||
optional TestRecursiveMessage a = 1;
|
||||
optional int32 i = 2;
|
||||
}
|
||||
|
||||
// Test that mutual recursion works.
|
||||
message TestMutualRecursionA {
|
||||
optional TestMutualRecursionB bb = 1;
|
||||
}
|
||||
|
||||
message TestMutualRecursionB {
|
||||
optional TestMutualRecursionA a = 1;
|
||||
optional int32 optional_int32 = 2;
|
||||
}
|
||||
|
||||
// Test that groups have disjoint field numbers from their siblings and
|
||||
// parents. This is NOT possible in proto1; only proto2. When outputting
|
||||
// proto1, the dup fields should be dropped.
|
||||
message TestDupFieldNumber {
|
||||
optional int32 a = 1;
|
||||
optional group Foo = 2 { optional int32 a = 1; }
|
||||
optional group Bar = 3 { optional int32 a = 1; }
|
||||
}
|
||||
|
||||
|
||||
// Needed for a Python test.
|
||||
message TestNestedMessageHasBits {
|
||||
message NestedMessage {
|
||||
repeated int32 nestedmessage_repeated_int32 = 1;
|
||||
repeated ForeignMessage nestedmessage_repeated_foreignmessage = 2;
|
||||
}
|
||||
optional NestedMessage optional_nested_message = 1;
|
||||
}
|
||||
|
||||
|
||||
// Test an enum that has multiple values with the same number.
|
||||
enum TestEnumWithDupValue {
|
||||
FOO1 = 1;
|
||||
BAR1 = 2;
|
||||
BAZ = 3;
|
||||
FOO2 = 1;
|
||||
BAR2 = 2;
|
||||
}
|
||||
|
||||
// Test an enum with large, unordered values.
|
||||
enum TestSparseEnum {
|
||||
SPARSE_A = 123;
|
||||
SPARSE_B = 62374;
|
||||
SPARSE_C = 12589234;
|
||||
SPARSE_D = -15;
|
||||
SPARSE_E = -53452;
|
||||
SPARSE_F = 0;
|
||||
SPARSE_G = 2;
|
||||
}
|
||||
|
||||
// Test message with CamelCase field names. This violates Protocol Buffer
|
||||
// standard style.
|
||||
message TestCamelCaseFieldNames {
|
||||
optional int32 PrimitiveField = 1;
|
||||
optional string StringField = 2;
|
||||
optional ForeignEnum EnumField = 3;
|
||||
optional ForeignMessage MessageField = 4;
|
||||
optional string StringPieceField = 5 [ctype=STRING_PIECE];
|
||||
optional string CordField = 6 [ctype=CORD];
|
||||
|
||||
repeated int32 RepeatedPrimitiveField = 7;
|
||||
repeated string RepeatedStringField = 8;
|
||||
repeated ForeignEnum RepeatedEnumField = 9;
|
||||
repeated ForeignMessage RepeatedMessageField = 10;
|
||||
repeated string RepeatedStringPieceField = 11 [ctype=STRING_PIECE];
|
||||
repeated string RepeatedCordField = 12 [ctype=CORD];
|
||||
}
|
||||
|
||||
|
||||
// We list fields out of order, to ensure that we're using field number and not
|
||||
// field index to determine serialization order.
|
||||
message TestFieldOrderings {
|
||||
optional string my_string = 11;
|
||||
extensions 2 to 10;
|
||||
optional int64 my_int = 1;
|
||||
extensions 12 to 100;
|
||||
optional float my_float = 101;
|
||||
}
|
||||
|
||||
|
||||
extend TestFieldOrderings {
|
||||
optional string my_extension_string = 50;
|
||||
optional int32 my_extension_int = 5;
|
||||
}
|
||||
|
||||
|
||||
message TestExtremeDefaultValues {
|
||||
optional bytes escaped_bytes = 1 [default = "\0\001\a\b\f\n\r\t\v\\\'\"\xfe"];
|
||||
optional uint32 large_uint32 = 2 [default = 0xFFFFFFFF];
|
||||
optional uint64 large_uint64 = 3 [default = 0xFFFFFFFFFFFFFFFF];
|
||||
optional int32 small_int32 = 4 [default = -0x7FFFFFFF];
|
||||
optional int64 small_int64 = 5 [default = -0x7FFFFFFFFFFFFFFF];
|
||||
|
||||
// The default value here is UTF-8 for "\u1234". (We could also just type
|
||||
// the UTF-8 text directly into this text file rather than escape it, but
|
||||
// lots of people use editors that would be confused by this.)
|
||||
optional string utf8_string = 6 [default = "\341\210\264"];
|
||||
}
|
||||
|
||||
// Test that RPC services work.
|
||||
message FooRequest {}
|
||||
message FooResponse {}
|
||||
|
||||
service TestService {
|
||||
rpc Foo(FooRequest) returns (FooResponse);
|
||||
rpc Bar(BarRequest) returns (BarResponse);
|
||||
}
|
||||
|
||||
|
||||
message BarRequest {}
|
||||
message BarResponse {}
|
|
@ -0,0 +1,36 @@
|
|||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc.
|
||||
// http://code.google.com/p/protobuf/
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Author: kenton@google.com (Kenton Varda)
|
||||
// Based on original Protocol Buffers design by
|
||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||
//
|
||||
// A proto file which imports a proto file that uses optimize_for = CODE_SIZE.
|
||||
|
||||
import "unittest_optimize_for.proto";
|
||||
|
||||
package protobuf_unittest;
|
||||
|
||||
// We optimize for speed here, but we are importing a proto that is optimized
|
||||
// for code size.
|
||||
option optimize_for = SPEED;
|
||||
|
||||
message TestEmbedOptimizedForSize {
|
||||
// Test that embedding a message which has optimize_for = CODE_SIZE into
|
||||
// one optimized for speed works.
|
||||
optional TestOptimizedForSize optional_message = 1;
|
||||
repeated TestOptimizedForSize repeated_message = 2;
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc.
|
||||
// http://code.google.com/p/protobuf/
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Author: kenton@google.com (Kenton Varda)
|
||||
// Based on original Protocol Buffers design by
|
||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||
//
|
||||
// A proto file which is imported by unittest.proto to test importing.
|
||||
|
||||
|
||||
// We don't put this in a package within proto2 because we need to make sure
|
||||
// that the generated code doesn't depend on being in the proto2 namespace.
|
||||
// In test_util.h we do
|
||||
// "using namespace unittest_import = protobuf_unittest_import".
|
||||
package protobuf_unittest_import;
|
||||
|
||||
option optimize_for = SPEED;
|
||||
|
||||
// Excercise the java_package option.
|
||||
option java_package = "com.google.protobuf.test";
|
||||
|
||||
// Do not set a java_outer_classname here to verify that Proto2 works without
|
||||
// one.
|
||||
|
||||
message ImportMessage {
|
||||
optional int32 d = 1;
|
||||
}
|
||||
|
||||
enum ImportEnum {
|
||||
IMPORT_FOO = 7;
|
||||
IMPORT_BAR = 8;
|
||||
IMPORT_BAZ = 9;
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc.
|
||||
// http://code.google.com/p/protobuf/
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Author: kenton@google.com (Kenton Varda)
|
||||
// Based on original Protocol Buffers design by
|
||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||
//
|
||||
// This file contains messages for testing message_set_wire_format.
|
||||
|
||||
package protobuf_unittest;
|
||||
|
||||
option optimize_for = SPEED;
|
||||
|
||||
// A message with message_set_wire_format.
|
||||
message TestMessageSet {
|
||||
option message_set_wire_format = true;
|
||||
extensions 4 to max;
|
||||
}
|
||||
|
||||
message TestMessageSetContainer {
|
||||
optional TestMessageSet message_set = 1;
|
||||
}
|
||||
|
||||
message TestMessageSetExtension1 {
|
||||
extend TestMessageSet {
|
||||
optional TestMessageSetExtension1 message_set_extension = 1545008;
|
||||
}
|
||||
optional int32 i = 15;
|
||||
}
|
||||
|
||||
message TestMessageSetExtension2 {
|
||||
extend TestMessageSet {
|
||||
optional TestMessageSetExtension2 message_set_extension = 1547769;
|
||||
}
|
||||
optional string str = 25;
|
||||
}
|
||||
|
||||
// MessageSet wire format is equivalent to this.
|
||||
message RawMessageSet {
|
||||
repeated group Item = 1 {
|
||||
required int32 type_id = 2;
|
||||
required bytes message = 3;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc.
|
||||
// http://code.google.com/p/protobuf/
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Author: kenton@google.com (Kenton Varda)
|
||||
// Based on original Protocol Buffers design by
|
||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||
//
|
||||
// A proto file which uses optimize_for = CODE_SIZE.
|
||||
|
||||
import "unittest.proto";
|
||||
|
||||
package protobuf_unittest;
|
||||
|
||||
option optimize_for = CODE_SIZE;
|
||||
|
||||
message TestOptimizedForSize {
|
||||
optional int32 i = 1;
|
||||
optional ForeignMessage msg = 19;
|
||||
|
||||
extensions 1000 to max;
|
||||
|
||||
extend TestOptimizedForSize {
|
||||
optional int32 test_extension = 1234;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc.
|
||||
// http://code.google.com/p/protobuf/
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.protobuf;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import protobuf_unittest.EnumWithNoOuter;
|
||||
import protobuf_unittest.MessageWithNoOuter;
|
||||
import protobuf_unittest.UnittestProto.ForeignEnum;
|
||||
import protobuf_unittest.UnittestProto.ForeignMessage;
|
||||
import protobuf_unittest.UnittestProto.TestAllTypes;
|
||||
import protobuf_unittest.UnittestProto.TestExtremeDefaultValues;
|
||||
|
||||
/**
|
||||
* Unit test for generated messages and generated code. See also
|
||||
* {@link MessageTest}, which tests some generated message functionality.
|
||||
*
|
||||
* @author kenton@google.com Kenton Varda
|
||||
*/
|
||||
public class GeneratedMessageTest extends TestCase {
|
||||
|
||||
|
||||
public void testAccessors() throws Exception {
|
||||
TestAllTypes builder = new TestAllTypes();
|
||||
TestUtil.setAllFields(builder);
|
||||
TestAllTypes message = builder;
|
||||
TestUtil.assertAllFieldsSet(message);
|
||||
}
|
||||
|
||||
public void testRepeatedSetters() throws Exception {
|
||||
TestAllTypes builder = new TestAllTypes();
|
||||
TestUtil.setAllFields(builder);
|
||||
TestUtil.modifyRepeatedFields(builder);
|
||||
TestAllTypes message = builder;
|
||||
TestUtil.assertRepeatedFieldsModified(message);
|
||||
}
|
||||
|
||||
public void testRepeatedAppend() throws Exception {
|
||||
TestAllTypes builder = new TestAllTypes();
|
||||
|
||||
builder.addAllRepeatedInt32(Arrays.asList(1, 2, 3, 4));
|
||||
builder.addAllRepeatedForeignEnum(Arrays.asList(ForeignEnum.FOREIGN_BAZ));
|
||||
|
||||
ForeignMessage foreignMessage = new ForeignMessage().setC(12);
|
||||
builder.addAllRepeatedForeignMessage(Arrays.asList(foreignMessage));
|
||||
|
||||
TestAllTypes message = builder;
|
||||
assertEquals(message.getRepeatedInt32List(), Arrays.asList(1, 2, 3, 4));
|
||||
assertEquals(message.getRepeatedForeignEnumList(),
|
||||
Arrays.asList(ForeignEnum.FOREIGN_BAZ));
|
||||
assertEquals(1, message.getRepeatedForeignMessageCount());
|
||||
assertEquals(12, message.getRepeatedForeignMessage(0).getC());
|
||||
}
|
||||
|
||||
public void testSettingForeignMessageUsingBuilder() throws Exception {
|
||||
TestAllTypes message = new TestAllTypes()
|
||||
// Pass builder for foreign message instance.
|
||||
.setOptionalForeignMessage(new ForeignMessage().setC(123))
|
||||
;
|
||||
TestAllTypes expectedMessage = new TestAllTypes()
|
||||
// Create expected version passing foreign message instance explicitly.
|
||||
.setOptionalForeignMessage(new ForeignMessage().setC(123))
|
||||
;
|
||||
// TODO(ngd): Upgrade to using real #equals method once implemented
|
||||
assertEquals(expectedMessage.toString(), message.toString());
|
||||
}
|
||||
|
||||
public void testSettingRepeatedForeignMessageUsingBuilder() throws Exception {
|
||||
TestAllTypes message = new TestAllTypes()
|
||||
// Pass builder for foreign message instance.
|
||||
.addRepeatedForeignMessage(new ForeignMessage().setC(456))
|
||||
;
|
||||
TestAllTypes expectedMessage = new TestAllTypes()
|
||||
// Create expected version passing foreign message instance explicitly.
|
||||
.addRepeatedForeignMessage(
|
||||
new ForeignMessage().setC(456))
|
||||
;
|
||||
assertEquals(expectedMessage.toString(), message.toString());
|
||||
}
|
||||
|
||||
public void testDefaults() throws Exception {
|
||||
TestUtil.assertClear(new TestAllTypes());
|
||||
|
||||
assertEquals("\u1234", new TestExtremeDefaultValues().getUtf8String());
|
||||
}
|
||||
|
||||
// =================================================================
|
||||
// multiple_files_test
|
||||
|
||||
public void testMultipleFilesOption() throws Exception {
|
||||
// We mostly just want to check that things compile.
|
||||
MessageWithNoOuter message =
|
||||
new MessageWithNoOuter()
|
||||
.setNested(new MessageWithNoOuter.NestedMessage().setI(1))
|
||||
.addForeign(new TestAllTypes().setOptionalInt32(1))
|
||||
.setNestedEnum(MessageWithNoOuter.NestedEnum.BAZ)
|
||||
.setForeignEnum(EnumWithNoOuter.BAR)
|
||||
;
|
||||
|
||||
byte[] data = message.toUnframedByteArray();
|
||||
MessageWithNoOuter newMessage = MessageWithNoOuter.parseUnframed(data);
|
||||
assertEquals(message.toString(), newMessage.toString());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc.
|
||||
// http://code.google.com/p/protobuf/
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.protobuf;
|
||||
|
||||
import protobuf_unittest.UnittestProto.TestAllTypes;
|
||||
import protobuf_unittest.UnittestProto.TestRequired;
|
||||
import protobuf_unittest.UnittestProto.TestRequiredForeign;
|
||||
import protobuf_unittest.UnittestProto.ForeignMessage;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Misc. unit tests for message operations that apply to both generated
|
||||
* and dynamic messages.
|
||||
*
|
||||
* @author kenton@google.com Kenton Varda
|
||||
*/
|
||||
public class MessageTest extends TestCase {
|
||||
// =================================================================
|
||||
// Message-merging tests.
|
||||
|
||||
static final TestAllTypes MERGE_SOURCE =
|
||||
new TestAllTypes()
|
||||
.setOptionalInt32(1)
|
||||
.setOptionalString("foo")
|
||||
.setOptionalForeignMessage(new ForeignMessage())
|
||||
.addRepeatedString("bar")
|
||||
;
|
||||
|
||||
static final TestAllTypes MERGE_DEST =
|
||||
new TestAllTypes()
|
||||
.setOptionalInt64(2)
|
||||
.setOptionalString("baz")
|
||||
.setOptionalForeignMessage(new ForeignMessage().setC(3))
|
||||
.addRepeatedString("qux")
|
||||
;
|
||||
|
||||
static final String MERGE_RESULT_TEXT =
|
||||
"optional_int32: 1\n" +
|
||||
"optional_int64: 2\n" +
|
||||
"optional_string: foo\n" +
|
||||
"optional_foreign_message {\n" +
|
||||
" c: 3\n" +
|
||||
"}\n" +
|
||||
"repeated_string[0]: qux\n" +
|
||||
"repeated_string[1]: bar\n";
|
||||
|
||||
public void testMergeFrom() throws Exception {
|
||||
TestAllTypes result =
|
||||
new TestAllTypes().mergeFrom(MERGE_DEST)
|
||||
.mergeFrom(MERGE_SOURCE);
|
||||
|
||||
assertEquals(MERGE_RESULT_TEXT, result.toString());
|
||||
}
|
||||
|
||||
|
||||
// =================================================================
|
||||
// Required-field-related tests.
|
||||
|
||||
private static final TestRequired TEST_REQUIRED_UNINITIALIZED =
|
||||
new TestRequired();
|
||||
private static final TestRequired TEST_REQUIRED_INITIALIZED =
|
||||
new TestRequired().setA(1).setB(2).setC(3);
|
||||
|
||||
public void testRequired() throws Exception {
|
||||
TestRequired builder = new TestRequired();
|
||||
|
||||
assertFalse(builder.isInitialized());
|
||||
builder.setA(1);
|
||||
assertFalse(builder.isInitialized());
|
||||
builder.setB(1);
|
||||
assertFalse(builder.isInitialized());
|
||||
builder.setC(1);
|
||||
assertTrue(builder.isInitialized());
|
||||
}
|
||||
|
||||
public void testRequiredForeign() throws Exception {
|
||||
TestRequiredForeign builder = new TestRequiredForeign();
|
||||
|
||||
assertTrue(builder.isInitialized());
|
||||
|
||||
builder.setOptionalMessage(TEST_REQUIRED_UNINITIALIZED);
|
||||
assertFalse(builder.isInitialized());
|
||||
|
||||
builder.setOptionalMessage(TEST_REQUIRED_INITIALIZED);
|
||||
assertTrue(builder.isInitialized());
|
||||
|
||||
builder.addRepeatedMessage(TEST_REQUIRED_UNINITIALIZED);
|
||||
assertFalse(builder.isInitialized());
|
||||
|
||||
builder.setRepeatedMessage(0, TEST_REQUIRED_INITIALIZED);
|
||||
assertTrue(builder.isInitialized());
|
||||
}
|
||||
|
||||
|
||||
public void testIsInitialized() throws Exception {
|
||||
assertFalse(new TestRequired().isInitialized());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,791 @@
|
|||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc.
|
||||
// http://code.google.com/p/protobuf/
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Note: This file contains many lines over 80 characters. It even contains
|
||||
// many lines over 100 characters, which fails a presubmit test. However,
|
||||
// given the extremely repetitive nature of the file, I (kenton) feel that
|
||||
// having similar components of each statement line up is more important than
|
||||
// avoiding horizontal scrolling. So, I am bypassing the presubmit check.
|
||||
|
||||
package com.google.protobuf;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
|
||||
import org.apache.activemq.protobuf.Buffer;
|
||||
|
||||
import protobuf_unittest.UnittestProto.ForeignEnum;
|
||||
import protobuf_unittest.UnittestProto.ForeignMessage;
|
||||
import protobuf_unittest.UnittestProto.TestAllTypes;
|
||||
|
||||
import com.google.protobuf.test.UnittestImport.ImportEnum;
|
||||
import com.google.protobuf.test.UnittestImport.ImportMessage;
|
||||
|
||||
/**
|
||||
* Contains methods for setting all fields of {@code TestAllTypes} to
|
||||
* some vaules as well as checking that all the fields are set to those values.
|
||||
* These are useful for testing various protocol message features, e.g.
|
||||
* set all fields of a message, serialize it, parse it, and check that all
|
||||
* fields are set.
|
||||
*
|
||||
* @author kenton@google.com Kenton Varda
|
||||
*/
|
||||
class TestUtil {
|
||||
private TestUtil() {}
|
||||
|
||||
/** Helper to convert a String to ByteSequence. */
|
||||
private static Buffer toBytes(String str) {
|
||||
try {
|
||||
return new Buffer(str.getBytes("UTF-8"));
|
||||
} catch(java.io.UnsupportedEncodingException e) {
|
||||
throw new RuntimeException("UTF-8 not supported.", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a {@code TestAllTypes} with all fields set as they would be by
|
||||
* {@link #setAllFields(TestAllTypes.Builder)}.
|
||||
*/
|
||||
public static TestAllTypes getAllSet() {
|
||||
TestAllTypes builder = new TestAllTypes();
|
||||
setAllFields(builder);
|
||||
return builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set every field of {@code message} to the values expected by
|
||||
* {@code assertAllFieldsSet()}.
|
||||
*/
|
||||
public static void setAllFields(protobuf_unittest.UnittestProto.TestAllTypes message) {
|
||||
message.setOptionalInt32 (101);
|
||||
message.setOptionalInt64 (102);
|
||||
message.setOptionalUint32 (103);
|
||||
message.setOptionalUint64 (104);
|
||||
message.setOptionalSint32 (105);
|
||||
message.setOptionalSint64 (106);
|
||||
message.setOptionalFixed32 (107);
|
||||
message.setOptionalFixed64 (108);
|
||||
message.setOptionalSfixed32(109);
|
||||
message.setOptionalSfixed64(110);
|
||||
message.setOptionalFloat (111);
|
||||
message.setOptionalDouble (112);
|
||||
message.setOptionalBool (true);
|
||||
message.setOptionalString ("115");
|
||||
message.setOptionalBytes (toBytes("116"));
|
||||
|
||||
message.setOptionalGroup(
|
||||
new TestAllTypes.OptionalGroup().setA(117));
|
||||
message.setOptionalNestedMessage(
|
||||
new TestAllTypes.NestedMessage().setBb(118));
|
||||
message.setOptionalForeignMessage(
|
||||
new ForeignMessage().setC(119));
|
||||
message.setOptionalImportMessage(
|
||||
new ImportMessage().setD(120));
|
||||
|
||||
message.setOptionalNestedEnum (TestAllTypes.NestedEnum.BAZ);
|
||||
message.setOptionalForeignEnum(ForeignEnum.FOREIGN_BAZ);
|
||||
message.setOptionalImportEnum (ImportEnum.IMPORT_BAZ);
|
||||
|
||||
message.setOptionalStringPiece("124");
|
||||
message.setOptionalCord("125");
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
message.getRepeatedInt32List().add(201);
|
||||
message.getRepeatedInt64List().add(202L);
|
||||
message.getRepeatedUint32List().add(203);
|
||||
message.getRepeatedUint64List().add(204l);
|
||||
message.getRepeatedSint32List().add(205);
|
||||
message.getRepeatedSint64List().add (206l);
|
||||
message.getRepeatedFixed32List().add (207);
|
||||
message.getRepeatedFixed64List().add (208l);
|
||||
message.getRepeatedSfixed32List().add(209);
|
||||
message.getRepeatedSfixed64List().add(210l);
|
||||
message.getRepeatedFloatList().add (211f);
|
||||
message.getRepeatedDoubleList().add (212d);
|
||||
message.getRepeatedBoolList().add (true);
|
||||
message.getRepeatedStringList().add ("215");
|
||||
message.getRepeatedBytesList().add (toBytes("216"));
|
||||
|
||||
message.getRepeatedGroupList().add(
|
||||
new TestAllTypes.RepeatedGroup().setA(217));
|
||||
message.getRepeatedNestedMessageList().add(
|
||||
new TestAllTypes.NestedMessage().setBb(218));
|
||||
message.getRepeatedForeignMessageList().add(
|
||||
new ForeignMessage().setC(219));
|
||||
message.getRepeatedImportMessageList().add(
|
||||
new ImportMessage().setD(220));
|
||||
|
||||
message.getRepeatedNestedEnumList().add(TestAllTypes.NestedEnum.BAR);
|
||||
message.getRepeatedForeignEnumList().add(ForeignEnum.FOREIGN_BAR);
|
||||
message.getRepeatedImportEnumList().add(ImportEnum.IMPORT_BAR);
|
||||
|
||||
message.getRepeatedStringPieceList().add("224");
|
||||
message.getRepeatedCordList().add("225");
|
||||
|
||||
// Add a second one of each field.
|
||||
message.getRepeatedInt32List().add(301);
|
||||
message.getRepeatedInt64List().add(302L);
|
||||
message.getRepeatedUint32List().add(303);
|
||||
message.getRepeatedUint64List().add(304l);
|
||||
message.getRepeatedSint32List().add(305);
|
||||
message.getRepeatedSint64List().add (306l);
|
||||
message.getRepeatedFixed32List().add (307);
|
||||
message.getRepeatedFixed64List().add (308l);
|
||||
message.getRepeatedSfixed32List().add(309);
|
||||
message.getRepeatedSfixed64List().add(310l);
|
||||
message.getRepeatedFloatList().add (311f);
|
||||
message.getRepeatedDoubleList().add (312d);
|
||||
message.getRepeatedBoolList().add (false);
|
||||
message.getRepeatedStringList().add ("315");
|
||||
message.getRepeatedBytesList().add (toBytes("316"));
|
||||
|
||||
message.getRepeatedGroupList().add(
|
||||
new TestAllTypes.RepeatedGroup().setA(317));
|
||||
message.getRepeatedNestedMessageList().add(
|
||||
new TestAllTypes.NestedMessage().setBb(318));
|
||||
message.getRepeatedForeignMessageList().add(
|
||||
new ForeignMessage().setC(319));
|
||||
message.getRepeatedImportMessageList().add(
|
||||
new ImportMessage().setD(320));
|
||||
|
||||
message.getRepeatedNestedEnumList().add(TestAllTypes.NestedEnum.BAZ);
|
||||
message.getRepeatedForeignEnumList().add(ForeignEnum.FOREIGN_BAZ);
|
||||
message.getRepeatedImportEnumList().add(ImportEnum.IMPORT_BAZ);
|
||||
|
||||
message.getRepeatedStringPieceList().add("324");
|
||||
message.getRepeatedCordList().add("325");
|
||||
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
message.setDefaultInt32 (401);
|
||||
message.setDefaultInt64 (402);
|
||||
message.setDefaultUint32 (403);
|
||||
message.setDefaultUint64 (404);
|
||||
message.setDefaultSint32 (405);
|
||||
message.setDefaultSint64 (406);
|
||||
message.setDefaultFixed32 (407);
|
||||
message.setDefaultFixed64 (408);
|
||||
message.setDefaultSfixed32(409);
|
||||
message.setDefaultSfixed64(410);
|
||||
message.setDefaultFloat (411);
|
||||
message.setDefaultDouble (412);
|
||||
message.setDefaultBool (false);
|
||||
message.setDefaultString ("415");
|
||||
message.setDefaultBytes (toBytes("416"));
|
||||
|
||||
message.setDefaultNestedEnum (TestAllTypes.NestedEnum.FOO);
|
||||
message.setDefaultForeignEnum(ForeignEnum.FOREIGN_FOO);
|
||||
message.setDefaultImportEnum (ImportEnum.IMPORT_FOO);
|
||||
|
||||
message.setDefaultStringPiece("424");
|
||||
message.setDefaultCord("425");
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Modify the repeated fields of {@code message} to contain the values
|
||||
* expected by {@code assertRepeatedFieldsModified()}.
|
||||
*/
|
||||
public static void modifyRepeatedFields(TestAllTypes message) {
|
||||
message.getRepeatedInt32List().set(1, 501);
|
||||
message.getRepeatedInt64List().set (1, 502l);
|
||||
message.getRepeatedUint32List().set (1, 503);
|
||||
message.getRepeatedUint64List().set (1, 504l);
|
||||
message.getRepeatedSint32List().set (1, 505);
|
||||
message.getRepeatedSint64List().set (1, 506l);
|
||||
message.getRepeatedFixed32List().set (1, 507);
|
||||
message.getRepeatedFixed64List().set (1, 508l);
|
||||
message.getRepeatedSfixed32List().set(1, 509);
|
||||
message.getRepeatedSfixed64List().set(1, 510l);
|
||||
message.getRepeatedFloatList().set (1, 511f);
|
||||
message.getRepeatedDoubleList().set (1, 512d);
|
||||
message.getRepeatedBoolList().set (1, true);
|
||||
message.getRepeatedStringList().set (1, "515");
|
||||
message.getRepeatedBytesList().set (1, toBytes("516"));
|
||||
|
||||
message.getRepeatedGroupList().set(1,
|
||||
new TestAllTypes.RepeatedGroup().setA(517));
|
||||
message.getRepeatedNestedMessageList().set(1,
|
||||
new TestAllTypes.NestedMessage().setBb(518));
|
||||
message.getRepeatedForeignMessageList().set(1,
|
||||
new ForeignMessage().setC(519));
|
||||
message.getRepeatedImportMessageList().set(1,
|
||||
new ImportMessage().setD(520));
|
||||
|
||||
message.getRepeatedNestedEnumList().set (1, TestAllTypes.NestedEnum.FOO);
|
||||
message.getRepeatedForeignEnumList().set(1, ForeignEnum.FOREIGN_FOO);
|
||||
message.getRepeatedImportEnumList().set (1, ImportEnum.IMPORT_FOO);
|
||||
|
||||
message.getRepeatedStringPieceList().set(1, "524");
|
||||
message.getRepeatedCordList().set(1, "525");
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Assert (using {@code junit.framework.Assert}} that all fields of
|
||||
* {@code message} are set to the values assigned by {@code setAllFields}.
|
||||
*/
|
||||
public static void assertAllFieldsSet(TestAllTypes message) {
|
||||
assertTrue(message.hasOptionalInt32 ());
|
||||
assertTrue(message.hasOptionalInt64 ());
|
||||
assertTrue(message.hasOptionalUint32 ());
|
||||
assertTrue(message.hasOptionalUint64 ());
|
||||
assertTrue(message.hasOptionalSint32 ());
|
||||
assertTrue(message.hasOptionalSint64 ());
|
||||
assertTrue(message.hasOptionalFixed32 ());
|
||||
assertTrue(message.hasOptionalFixed64 ());
|
||||
assertTrue(message.hasOptionalSfixed32());
|
||||
assertTrue(message.hasOptionalSfixed64());
|
||||
assertTrue(message.hasOptionalFloat ());
|
||||
assertTrue(message.hasOptionalDouble ());
|
||||
assertTrue(message.hasOptionalBool ());
|
||||
assertTrue(message.hasOptionalString ());
|
||||
assertTrue(message.hasOptionalBytes ());
|
||||
|
||||
assertTrue(message.hasOptionalGroup ());
|
||||
assertTrue(message.hasOptionalNestedMessage ());
|
||||
assertTrue(message.hasOptionalForeignMessage());
|
||||
assertTrue(message.hasOptionalImportMessage ());
|
||||
|
||||
assertTrue(message.getOptionalGroup ().hasA());
|
||||
assertTrue(message.getOptionalNestedMessage ().hasBb());
|
||||
assertTrue(message.getOptionalForeignMessage().hasC());
|
||||
assertTrue(message.getOptionalImportMessage ().hasD());
|
||||
|
||||
assertTrue(message.hasOptionalNestedEnum ());
|
||||
assertTrue(message.hasOptionalForeignEnum());
|
||||
assertTrue(message.hasOptionalImportEnum ());
|
||||
|
||||
assertTrue(message.hasOptionalStringPiece());
|
||||
assertTrue(message.hasOptionalCord());
|
||||
|
||||
assertEquals(101 , message.getOptionalInt32 ());
|
||||
assertEquals(102 , message.getOptionalInt64 ());
|
||||
assertEquals(103 , message.getOptionalUint32 ());
|
||||
assertEquals(104 , message.getOptionalUint64 ());
|
||||
assertEquals(105 , message.getOptionalSint32 ());
|
||||
assertEquals(106 , message.getOptionalSint64 ());
|
||||
assertEquals(107 , message.getOptionalFixed32 ());
|
||||
assertEquals(108 , message.getOptionalFixed64 ());
|
||||
assertEquals(109 , message.getOptionalSfixed32());
|
||||
assertEquals(110 , message.getOptionalSfixed64());
|
||||
assertEquals(111 , message.getOptionalFloat (), 0.0);
|
||||
assertEquals(112 , message.getOptionalDouble (), 0.0);
|
||||
assertEquals(true , message.getOptionalBool ());
|
||||
assertEquals("115", message.getOptionalString ());
|
||||
assertEquals(toBytes("116"), message.getOptionalBytes());
|
||||
|
||||
assertEquals(117, message.getOptionalGroup ().getA());
|
||||
assertEquals(118, message.getOptionalNestedMessage ().getBb());
|
||||
assertEquals(119, message.getOptionalForeignMessage().getC());
|
||||
assertEquals(120, message.getOptionalImportMessage ().getD());
|
||||
|
||||
assertEquals(TestAllTypes.NestedEnum.BAZ, message.getOptionalNestedEnum());
|
||||
assertEquals(ForeignEnum.FOREIGN_BAZ, message.getOptionalForeignEnum());
|
||||
assertEquals(ImportEnum.IMPORT_BAZ, message.getOptionalImportEnum());
|
||||
|
||||
assertEquals("124", message.getOptionalStringPiece());
|
||||
assertEquals("125", message.getOptionalCord());
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
assertEquals(2, message.getRepeatedInt32List().size ());
|
||||
assertEquals(2, message.getRepeatedInt64List().size ());
|
||||
assertEquals(2, message.getRepeatedUint32List().size ());
|
||||
assertEquals(2, message.getRepeatedUint64List().size ());
|
||||
assertEquals(2, message.getRepeatedSint32List().size ());
|
||||
assertEquals(2, message.getRepeatedSint64List().size ());
|
||||
assertEquals(2, message.getRepeatedFixed32List().size ());
|
||||
assertEquals(2, message.getRepeatedFixed64List().size ());
|
||||
assertEquals(2, message.getRepeatedSfixed32List().size());
|
||||
assertEquals(2, message.getRepeatedSfixed64List().size());
|
||||
assertEquals(2, message.getRepeatedFloatList().size ());
|
||||
assertEquals(2, message.getRepeatedDoubleList().size ());
|
||||
assertEquals(2, message.getRepeatedBoolList().size ());
|
||||
assertEquals(2, message.getRepeatedStringList().size ());
|
||||
assertEquals(2, message.getRepeatedBytesList().size ());
|
||||
|
||||
assertEquals(2, message.getRepeatedGroupList().size ());
|
||||
assertEquals(2, message.getRepeatedNestedMessageList().size ());
|
||||
assertEquals(2, message.getRepeatedForeignMessageList().size());
|
||||
assertEquals(2, message.getRepeatedImportMessageList().size ());
|
||||
assertEquals(2, message.getRepeatedNestedEnumList().size ());
|
||||
assertEquals(2, message.getRepeatedForeignEnumList().size ());
|
||||
assertEquals(2, message.getRepeatedImportEnumList().size ());
|
||||
|
||||
assertEquals(2, message.getRepeatedStringPieceList().size());
|
||||
assertEquals(2, message.getRepeatedCordList().size());
|
||||
|
||||
assertEquals(201 , (int)message.getRepeatedInt32List().get(0));
|
||||
assertEquals(202 , (long)message.getRepeatedInt64List().get (0));
|
||||
assertEquals(203 , (int)message.getRepeatedUint32List().get (0));
|
||||
assertEquals(204 , (long)message.getRepeatedUint64List().get (0));
|
||||
assertEquals(205 , (int)message.getRepeatedSint32List().get (0));
|
||||
assertEquals(206 , (long)message.getRepeatedSint64List().get (0));
|
||||
assertEquals(207 , (int)message.getRepeatedFixed32List().get (0));
|
||||
assertEquals(208 , (long)message.getRepeatedFixed64List().get (0));
|
||||
assertEquals(209 , (int)message.getRepeatedSfixed32List().get(0));
|
||||
assertEquals(210 , (long)message.getRepeatedSfixed64List().get(0));
|
||||
assertEquals(211 , message.getRepeatedFloatList().get (0), 0.0);
|
||||
assertEquals(212 , message.getRepeatedDoubleList().get (0), 0.0);
|
||||
assertEquals(true , (boolean)message.getRepeatedBoolList().get (0));
|
||||
assertEquals("215", message.getRepeatedStringList().get (0));
|
||||
assertEquals(toBytes("216"), message.getRepeatedBytesList().get(0));
|
||||
|
||||
assertEquals(217, message.getRepeatedGroupList().get (0).getA());
|
||||
assertEquals(218, message.getRepeatedNestedMessageList().get (0).getBb());
|
||||
assertEquals(219, message.getRepeatedForeignMessageList().get(0).getC());
|
||||
assertEquals(220, message.getRepeatedImportMessageList().get (0).getD());
|
||||
|
||||
assertEquals(TestAllTypes.NestedEnum.BAR, message.getRepeatedNestedEnumList().get (0));
|
||||
assertEquals(ForeignEnum.FOREIGN_BAR, message.getRepeatedForeignEnumList().get(0));
|
||||
assertEquals(ImportEnum.IMPORT_BAR, message.getRepeatedImportEnumList().get(0));
|
||||
|
||||
assertEquals("224", message.getRepeatedStringPieceList().get(0));
|
||||
assertEquals("225", message.getRepeatedCordList().get(0));
|
||||
|
||||
assertEquals(301 , (int)message.getRepeatedInt32List().get (1));
|
||||
assertEquals(302 , (long)message.getRepeatedInt64List().get (1));
|
||||
assertEquals(303 , (int)message.getRepeatedUint32List().get (1));
|
||||
assertEquals(304 , (long)message.getRepeatedUint64List().get (1));
|
||||
assertEquals(305 , (int)message.getRepeatedSint32List().get (1));
|
||||
assertEquals(306 , (long)message.getRepeatedSint64List().get (1));
|
||||
assertEquals(307 , (int)message.getRepeatedFixed32List().get (1));
|
||||
assertEquals(308 , (long)message.getRepeatedFixed64List().get (1));
|
||||
assertEquals(309 , (int)message.getRepeatedSfixed32List().get(1));
|
||||
assertEquals(310 , (long)message.getRepeatedSfixed64List().get(1));
|
||||
assertEquals(311 , message.getRepeatedFloatList().get (1), 0.0);
|
||||
assertEquals(312 , message.getRepeatedDoubleList().get (1), 0.0);
|
||||
assertEquals(false, (boolean)message.getRepeatedBoolList().get (1));
|
||||
assertEquals("315", message.getRepeatedStringList().get (1));
|
||||
assertEquals(toBytes("316"), message.getRepeatedBytesList().get(1));
|
||||
|
||||
assertEquals(317, message.getRepeatedGroupList().get (1).getA());
|
||||
assertEquals(318, message.getRepeatedNestedMessageList().get (1).getBb());
|
||||
assertEquals(319, message.getRepeatedForeignMessageList().get(1).getC());
|
||||
assertEquals(320, message.getRepeatedImportMessageList().get (1).getD());
|
||||
|
||||
assertEquals(TestAllTypes.NestedEnum.BAZ, message.getRepeatedNestedEnumList().get (1));
|
||||
assertEquals(ForeignEnum.FOREIGN_BAZ, message.getRepeatedForeignEnumList().get(1));
|
||||
assertEquals(ImportEnum.IMPORT_BAZ, message.getRepeatedImportEnumList().get(1));
|
||||
|
||||
assertEquals("324", message.getRepeatedStringPieceList().get(1));
|
||||
assertEquals("325", message.getRepeatedCordList().get(1));
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
assertTrue(message.hasDefaultInt32 ());
|
||||
assertTrue(message.hasDefaultInt64 ());
|
||||
assertTrue(message.hasDefaultUint32 ());
|
||||
assertTrue(message.hasDefaultUint64 ());
|
||||
assertTrue(message.hasDefaultSint32 ());
|
||||
assertTrue(message.hasDefaultSint64 ());
|
||||
assertTrue(message.hasDefaultFixed32 ());
|
||||
assertTrue(message.hasDefaultFixed64 ());
|
||||
assertTrue(message.hasDefaultSfixed32());
|
||||
assertTrue(message.hasDefaultSfixed64());
|
||||
assertTrue(message.hasDefaultFloat ());
|
||||
assertTrue(message.hasDefaultDouble ());
|
||||
assertTrue(message.hasDefaultBool ());
|
||||
assertTrue(message.hasDefaultString ());
|
||||
assertTrue(message.hasDefaultBytes ());
|
||||
|
||||
assertTrue(message.hasDefaultNestedEnum ());
|
||||
assertTrue(message.hasDefaultForeignEnum());
|
||||
assertTrue(message.hasDefaultImportEnum ());
|
||||
|
||||
assertTrue(message.hasDefaultStringPiece());
|
||||
assertTrue(message.hasDefaultCord());
|
||||
|
||||
assertEquals(401 , message.getDefaultInt32 ());
|
||||
assertEquals(402 , message.getDefaultInt64 ());
|
||||
assertEquals(403 , message.getDefaultUint32 ());
|
||||
assertEquals(404 , message.getDefaultUint64 ());
|
||||
assertEquals(405 , message.getDefaultSint32 ());
|
||||
assertEquals(406 , message.getDefaultSint64 ());
|
||||
assertEquals(407 , message.getDefaultFixed32 ());
|
||||
assertEquals(408 , message.getDefaultFixed64 ());
|
||||
assertEquals(409 , message.getDefaultSfixed32());
|
||||
assertEquals(410 , message.getDefaultSfixed64());
|
||||
assertEquals(411 , message.getDefaultFloat (), 0.0);
|
||||
assertEquals(412 , message.getDefaultDouble (), 0.0);
|
||||
assertEquals(false, message.getDefaultBool ());
|
||||
assertEquals("415", message.getDefaultString ());
|
||||
assertEquals(toBytes("416"), message.getDefaultBytes());
|
||||
|
||||
assertEquals(TestAllTypes.NestedEnum.FOO, message.getDefaultNestedEnum ());
|
||||
assertEquals(ForeignEnum.FOREIGN_FOO, message.getDefaultForeignEnum());
|
||||
assertEquals(ImportEnum.IMPORT_FOO, message.getDefaultImportEnum());
|
||||
|
||||
assertEquals("424", message.getDefaultStringPiece());
|
||||
assertEquals("425", message.getDefaultCord());
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Assert (using {@code junit.framework.Assert}} that all fields of
|
||||
* {@code message} are cleared, and that getting the fields returns their
|
||||
* default values.
|
||||
*/
|
||||
public static void assertClear(TestAllTypes message) {
|
||||
// hasBlah() should initially be false for all optional fields.
|
||||
assertFalse(message.hasOptionalInt32 ());
|
||||
assertFalse(message.hasOptionalInt64 ());
|
||||
assertFalse(message.hasOptionalUint32 ());
|
||||
assertFalse(message.hasOptionalUint64 ());
|
||||
assertFalse(message.hasOptionalSint32 ());
|
||||
assertFalse(message.hasOptionalSint64 ());
|
||||
assertFalse(message.hasOptionalFixed32 ());
|
||||
assertFalse(message.hasOptionalFixed64 ());
|
||||
assertFalse(message.hasOptionalSfixed32());
|
||||
assertFalse(message.hasOptionalSfixed64());
|
||||
assertFalse(message.hasOptionalFloat ());
|
||||
assertFalse(message.hasOptionalDouble ());
|
||||
assertFalse(message.hasOptionalBool ());
|
||||
assertFalse(message.hasOptionalString ());
|
||||
assertFalse(message.hasOptionalBytes ());
|
||||
|
||||
assertFalse(message.hasOptionalGroup ());
|
||||
assertFalse(message.hasOptionalNestedMessage ());
|
||||
assertFalse(message.hasOptionalForeignMessage());
|
||||
assertFalse(message.hasOptionalImportMessage ());
|
||||
|
||||
assertFalse(message.hasOptionalNestedEnum ());
|
||||
assertFalse(message.hasOptionalForeignEnum());
|
||||
assertFalse(message.hasOptionalImportEnum ());
|
||||
|
||||
assertFalse(message.hasOptionalStringPiece());
|
||||
assertFalse(message.hasOptionalCord());
|
||||
|
||||
// Optional fields without defaults are set to zero or something like it.
|
||||
assertEquals(0 , message.getOptionalInt32 ());
|
||||
assertEquals(0 , message.getOptionalInt64 ());
|
||||
assertEquals(0 , message.getOptionalUint32 ());
|
||||
assertEquals(0 , message.getOptionalUint64 ());
|
||||
assertEquals(0 , message.getOptionalSint32 ());
|
||||
assertEquals(0 , message.getOptionalSint64 ());
|
||||
assertEquals(0 , message.getOptionalFixed32 ());
|
||||
assertEquals(0 , message.getOptionalFixed64 ());
|
||||
assertEquals(0 , message.getOptionalSfixed32());
|
||||
assertEquals(0 , message.getOptionalSfixed64());
|
||||
assertEquals(0 , message.getOptionalFloat (), 0.0);
|
||||
assertEquals(0 , message.getOptionalDouble (), 0.0);
|
||||
assertEquals(false, message.getOptionalBool ());
|
||||
assertEquals(null , message.getOptionalString ());
|
||||
assertEquals(null, message.getOptionalBytes());
|
||||
assertEquals(null, message.getOptionalNestedEnum ());
|
||||
assertEquals(null, message.getOptionalForeignEnum());
|
||||
assertEquals(null, message.getOptionalImportEnum());
|
||||
assertEquals(null, message.getOptionalStringPiece());
|
||||
assertEquals(null, message.getOptionalCord());
|
||||
|
||||
// Embedded messages should also be clear.
|
||||
assertFalse(message.getOptionalGroup ().hasA());
|
||||
assertFalse(message.getOptionalNestedMessage ().hasBb());
|
||||
assertFalse(message.getOptionalForeignMessage().hasC());
|
||||
assertFalse(message.getOptionalImportMessage ().hasD());
|
||||
|
||||
assertEquals(0, message.getOptionalGroup ().getA());
|
||||
assertEquals(0, message.getOptionalNestedMessage ().getBb());
|
||||
assertEquals(0, message.getOptionalForeignMessage().getC());
|
||||
assertEquals(0, message.getOptionalImportMessage ().getD());
|
||||
|
||||
|
||||
|
||||
// Repeated fields are empty.
|
||||
assertEquals(0, message.getRepeatedInt32List().size ());
|
||||
assertEquals(0, message.getRepeatedInt64List().size ());
|
||||
assertEquals(0, message.getRepeatedUint32List().size ());
|
||||
assertEquals(0, message.getRepeatedUint64List().size ());
|
||||
assertEquals(0, message.getRepeatedSint32List().size ());
|
||||
assertEquals(0, message.getRepeatedSint64List().size ());
|
||||
assertEquals(0, message.getRepeatedFixed32List().size ());
|
||||
assertEquals(0, message.getRepeatedFixed64List().size ());
|
||||
assertEquals(0, message.getRepeatedSfixed32List().size());
|
||||
assertEquals(0, message.getRepeatedSfixed64List().size());
|
||||
assertEquals(0, message.getRepeatedFloatList().size ());
|
||||
assertEquals(0, message.getRepeatedDoubleList().size ());
|
||||
assertEquals(0, message.getRepeatedBoolList().size ());
|
||||
assertEquals(0, message.getRepeatedStringList().size ());
|
||||
assertEquals(0, message.getRepeatedBytesList().size ());
|
||||
|
||||
assertEquals(0, message.getRepeatedGroupList().size ());
|
||||
assertEquals(0, message.getRepeatedNestedMessageList().size ());
|
||||
assertEquals(0, message.getRepeatedForeignMessageList().size());
|
||||
assertEquals(0, message.getRepeatedImportMessageList().size ());
|
||||
assertEquals(0, message.getRepeatedNestedEnumList().size ());
|
||||
assertEquals(0, message.getRepeatedForeignEnumList().size ());
|
||||
assertEquals(0, message.getRepeatedImportEnumList().size ());
|
||||
|
||||
assertEquals(0, message.getRepeatedStringPieceList().size());
|
||||
assertEquals(0, message.getRepeatedCordList().size());
|
||||
|
||||
// hasBlah() should also be false for all default fields.
|
||||
assertFalse(message.hasDefaultInt32 ());
|
||||
assertFalse(message.hasDefaultInt64 ());
|
||||
assertFalse(message.hasDefaultUint32 ());
|
||||
assertFalse(message.hasDefaultUint64 ());
|
||||
assertFalse(message.hasDefaultSint32 ());
|
||||
assertFalse(message.hasDefaultSint64 ());
|
||||
assertFalse(message.hasDefaultFixed32 ());
|
||||
assertFalse(message.hasDefaultFixed64 ());
|
||||
assertFalse(message.hasDefaultSfixed32());
|
||||
assertFalse(message.hasDefaultSfixed64());
|
||||
assertFalse(message.hasDefaultFloat ());
|
||||
assertFalse(message.hasDefaultDouble ());
|
||||
assertFalse(message.hasDefaultBool ());
|
||||
assertFalse(message.hasDefaultString ());
|
||||
assertFalse(message.hasDefaultBytes ());
|
||||
|
||||
assertFalse(message.hasDefaultNestedEnum ());
|
||||
assertFalse(message.hasDefaultForeignEnum());
|
||||
assertFalse(message.hasDefaultImportEnum ());
|
||||
|
||||
assertFalse(message.hasDefaultStringPiece());
|
||||
assertFalse(message.hasDefaultCord());
|
||||
|
||||
// Fields with defaults have their default values (duh).
|
||||
assertEquals( 41 , message.getDefaultInt32 ());
|
||||
assertEquals( 42 , message.getDefaultInt64 ());
|
||||
assertEquals( 43 , message.getDefaultUint32 ());
|
||||
assertEquals( 44 , message.getDefaultUint64 ());
|
||||
assertEquals(-45 , message.getDefaultSint32 ());
|
||||
assertEquals( 46 , message.getDefaultSint64 ());
|
||||
assertEquals( 47 , message.getDefaultFixed32 ());
|
||||
assertEquals( 48 , message.getDefaultFixed64 ());
|
||||
assertEquals( 49 , message.getDefaultSfixed32());
|
||||
assertEquals(-50 , message.getDefaultSfixed64());
|
||||
assertEquals( 51.5 , message.getDefaultFloat (), 0.0);
|
||||
assertEquals( 52e3 , message.getDefaultDouble (), 0.0);
|
||||
assertEquals(true , message.getDefaultBool ());
|
||||
assertEquals("hello", message.getDefaultString ());
|
||||
assertEquals(toBytes("world"), message.getDefaultBytes());
|
||||
|
||||
assertEquals(TestAllTypes.NestedEnum.BAR, message.getDefaultNestedEnum ());
|
||||
assertEquals(ForeignEnum.FOREIGN_BAR, message.getDefaultForeignEnum());
|
||||
assertEquals(ImportEnum.IMPORT_BAR, message.getDefaultImportEnum());
|
||||
|
||||
assertEquals("abc", message.getDefaultStringPiece());
|
||||
assertEquals("123", message.getDefaultCord());
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Assert (using {@code junit.framework.Assert}} that all fields of
|
||||
* {@code message} are set to the values assigned by {@code setAllFields}
|
||||
* followed by {@code modifyRepeatedFields}.
|
||||
*/
|
||||
public static void assertRepeatedFieldsModified(TestAllTypes message) {
|
||||
// ModifyRepeatedFields only sets the second repeated element of each
|
||||
// field. In addition to verifying this, we also verify that the first
|
||||
// element and size were *not* modified.
|
||||
assertEquals(2, message.getRepeatedInt32List().size ());
|
||||
assertEquals(2, message.getRepeatedInt64List().size ());
|
||||
assertEquals(2, message.getRepeatedUint32List().size ());
|
||||
assertEquals(2, message.getRepeatedUint64List().size ());
|
||||
assertEquals(2, message.getRepeatedSint32List().size ());
|
||||
assertEquals(2, message.getRepeatedSint64List().size ());
|
||||
assertEquals(2, message.getRepeatedFixed32List().size ());
|
||||
assertEquals(2, message.getRepeatedFixed64List().size ());
|
||||
assertEquals(2, message.getRepeatedSfixed32List().size());
|
||||
assertEquals(2, message.getRepeatedSfixed64List().size());
|
||||
assertEquals(2, message.getRepeatedFloatList().size ());
|
||||
assertEquals(2, message.getRepeatedDoubleList().size ());
|
||||
assertEquals(2, message.getRepeatedBoolList().size ());
|
||||
assertEquals(2, message.getRepeatedStringList().size ());
|
||||
assertEquals(2, message.getRepeatedBytesList().size ());
|
||||
|
||||
assertEquals(2, message.getRepeatedGroupList().size ());
|
||||
assertEquals(2, message.getRepeatedNestedMessageList().size ());
|
||||
assertEquals(2, message.getRepeatedForeignMessageList().size());
|
||||
assertEquals(2, message.getRepeatedImportMessageList().size ());
|
||||
assertEquals(2, message.getRepeatedNestedEnumList().size ());
|
||||
assertEquals(2, message.getRepeatedForeignEnumList().size ());
|
||||
assertEquals(2, message.getRepeatedImportEnumList().size ());
|
||||
|
||||
assertEquals(2, message.getRepeatedStringPieceList().size());
|
||||
assertEquals(2, message.getRepeatedCordList().size());
|
||||
|
||||
assertEquals(201 , (int)message.getRepeatedInt32List().get (0));
|
||||
assertEquals(202L , (long)message.getRepeatedInt64List().get (0));
|
||||
assertEquals(203 , (int)message.getRepeatedUint32List().get (0));
|
||||
assertEquals(204L , (long)message.getRepeatedUint64List().get (0));
|
||||
assertEquals(205 , (int)message.getRepeatedSint32List().get (0));
|
||||
assertEquals(206L , (long)message.getRepeatedSint64List().get (0));
|
||||
assertEquals(207 , (int)message.getRepeatedFixed32List().get (0));
|
||||
assertEquals(208L , (long)message.getRepeatedFixed64List().get (0));
|
||||
assertEquals(209 , (int)message.getRepeatedSfixed32List().get(0));
|
||||
assertEquals(210L , (long)message.getRepeatedSfixed64List().get(0));
|
||||
assertEquals(Float.valueOf(211F) , Float.valueOf(message.getRepeatedFloatList().get(0)));
|
||||
assertEquals(Double.valueOf(212D), Double.valueOf(message.getRepeatedDoubleList().get(0)));
|
||||
assertEquals(true , (boolean)message.getRepeatedBoolList().get (0));
|
||||
assertEquals("215", message.getRepeatedStringList().get (0));
|
||||
assertEquals(toBytes("216"), message.getRepeatedBytesList().get(0));
|
||||
|
||||
assertEquals(217, message.getRepeatedGroupList().get (0).getA());
|
||||
assertEquals(218, message.getRepeatedNestedMessageList().get (0).getBb());
|
||||
assertEquals(219, message.getRepeatedForeignMessageList().get(0).getC());
|
||||
assertEquals(220, message.getRepeatedImportMessageList().get (0).getD());
|
||||
|
||||
assertEquals(TestAllTypes.NestedEnum.BAR, message.getRepeatedNestedEnumList().get (0));
|
||||
assertEquals(ForeignEnum.FOREIGN_BAR, message.getRepeatedForeignEnumList().get(0));
|
||||
assertEquals(ImportEnum.IMPORT_BAR, message.getRepeatedImportEnumList().get(0));
|
||||
|
||||
assertEquals("224", message.getRepeatedStringPieceList().get(0));
|
||||
assertEquals("225", message.getRepeatedCordList().get(0));
|
||||
|
||||
// Actually verify the second (modified) elements now.
|
||||
assertEquals(501 , (int)message.getRepeatedInt32List().get (1));
|
||||
assertEquals(502L , (long)message.getRepeatedInt64List().get (1));
|
||||
assertEquals(503 , (int)message.getRepeatedUint32List().get (1));
|
||||
assertEquals(504L , (long)message.getRepeatedUint64List().get (1));
|
||||
assertEquals(505 , (int)message.getRepeatedSint32List().get (1));
|
||||
assertEquals(506L , (long)message.getRepeatedSint64List().get (1));
|
||||
assertEquals(507 , (int)message.getRepeatedFixed32List().get (1));
|
||||
assertEquals(508L , (long)message.getRepeatedFixed64List().get (1));
|
||||
assertEquals(509 , (int)message.getRepeatedSfixed32List().get(1));
|
||||
assertEquals(510L , (long)message.getRepeatedSfixed64List().get(1));
|
||||
assertEquals(Float.valueOf(511F) , Float.valueOf(message.getRepeatedFloatList().get(1)));
|
||||
assertEquals(Double.valueOf(512D) , Double.valueOf(message.getRepeatedDoubleList().get(1)));
|
||||
assertEquals(true , (boolean)message.getRepeatedBoolList().get (1));
|
||||
assertEquals("515", message.getRepeatedStringList().get (1));
|
||||
assertEquals(toBytes("516"), message.getRepeatedBytesList().get(1));
|
||||
|
||||
assertEquals(517, message.getRepeatedGroupList().get (1).getA());
|
||||
assertEquals(518, message.getRepeatedNestedMessageList().get (1).getBb());
|
||||
assertEquals(519, message.getRepeatedForeignMessageList().get(1).getC());
|
||||
assertEquals(520, message.getRepeatedImportMessageList().get (1).getD());
|
||||
|
||||
assertEquals(TestAllTypes.NestedEnum.FOO, message.getRepeatedNestedEnumList().get (1));
|
||||
assertEquals(ForeignEnum.FOREIGN_FOO, message.getRepeatedForeignEnumList().get(1));
|
||||
assertEquals(ImportEnum.IMPORT_FOO, message.getRepeatedImportEnumList().get(1));
|
||||
|
||||
assertEquals("524", message.getRepeatedStringPieceList().get(1));
|
||||
assertEquals("525", message.getRepeatedCordList().get(1));
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
// Like above, but for extensions
|
||||
|
||||
// Java gets confused with things like assertEquals(int, Integer): it can't
|
||||
// decide whether to call assertEquals(int, int) or assertEquals(Object,
|
||||
// Object). So we define these methods to help it.
|
||||
private static void assertEqualsExactType(int a, int b) {
|
||||
assertEquals(a, b);
|
||||
}
|
||||
private static void assertEqualsExactType(long a, long b) {
|
||||
assertEquals(a, b);
|
||||
}
|
||||
private static void assertEqualsExactType(float a, float b) {
|
||||
assertEquals(a, b, 0.0);
|
||||
}
|
||||
private static void assertEqualsExactType(double a, double b) {
|
||||
assertEquals(a, b, 0.0);
|
||||
}
|
||||
private static void assertEqualsExactType(boolean a, boolean b) {
|
||||
assertEquals(a, b);
|
||||
}
|
||||
private static void assertEqualsExactType(String a, String b) {
|
||||
assertEquals(a, b);
|
||||
}
|
||||
private static void assertEqualsExactType(Buffer a, Buffer b) {
|
||||
assertEquals(a, b);
|
||||
}
|
||||
private static void assertEqualsExactType(TestAllTypes.NestedEnum a,
|
||||
TestAllTypes.NestedEnum b) {
|
||||
assertEquals(a, b);
|
||||
}
|
||||
private static void assertEqualsExactType(ForeignEnum a, ForeignEnum b) {
|
||||
assertEquals(a, b);
|
||||
}
|
||||
private static void assertEqualsExactType(ImportEnum a, ImportEnum b) {
|
||||
assertEquals(a, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param filePath The path relative to
|
||||
* {@link com.google.testing.util.TestUtil#getDefaultSrcDir}.
|
||||
*/
|
||||
public static String readTextFromFile(String filePath) {
|
||||
return readBytesFromFile(filePath).toStringUtf8();
|
||||
}
|
||||
|
||||
private static File getTestDataDir() {
|
||||
// Search each parent directory looking for "src/google/protobuf".
|
||||
File ancestor = new File(".");
|
||||
try {
|
||||
ancestor = ancestor.getCanonicalFile();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(
|
||||
"Couldn't get canonical name of working directory.", e);
|
||||
}
|
||||
while (ancestor != null && ancestor.exists()) {
|
||||
if (new File(ancestor, "src/google/protobuf").exists()) {
|
||||
return new File(ancestor, "src/google/protobuf/testdata");
|
||||
}
|
||||
ancestor = ancestor.getParentFile();
|
||||
}
|
||||
|
||||
throw new RuntimeException(
|
||||
"Could not find golden files. This test must be run from within the " +
|
||||
"protobuf source package so that it can read test data files from the " +
|
||||
"C++ source tree.");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param filePath The path relative to
|
||||
* {@link com.google.testing.util.TestUtil#getDefaultSrcDir}.
|
||||
*/
|
||||
public static Buffer readBytesFromFile(String filename) {
|
||||
File fullPath = new File(getTestDataDir(), filename);
|
||||
try(RandomAccessFile file = new RandomAccessFile(fullPath, "r")) {
|
||||
byte[] content = new byte[(int) file.length()];
|
||||
file.readFully(content);
|
||||
return new Buffer(content);
|
||||
} catch (IOException e) {
|
||||
// Throw a RuntimeException here so that we can call this function from
|
||||
// static initializers.
|
||||
throw new IllegalArgumentException(
|
||||
"Couldn't read file: " + fullPath.getPath(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the bytes of the "golden message". This is a serialized TestAllTypes
|
||||
* with all fields set as they would be by
|
||||
* {@link setAllFields(TestAllTypes.Builder)}, but it is loaded from a file
|
||||
* on disk rather than generated dynamically. The file is actually generated
|
||||
* by C++ code, so testing against it verifies compatibility with C++.
|
||||
*/
|
||||
public static Buffer getGoldenMessage() {
|
||||
if (goldenMessage == null) {
|
||||
goldenMessage = readBytesFromFile("golden_message");
|
||||
}
|
||||
return goldenMessage;
|
||||
}
|
||||
private static Buffer goldenMessage = null;
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc.
|
||||
// http://code.google.com/p/protobuf/
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package com.google.protobuf;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.activemq.protobuf.Buffer;
|
||||
import org.apache.activemq.protobuf.CodedInputStream;
|
||||
|
||||
import protobuf_unittest.UnittestProto.TestAllTypes;
|
||||
|
||||
/**
|
||||
* Tests related to parsing and serialization.
|
||||
*
|
||||
* @author kenton@google.com (Kenton Varda)
|
||||
*/
|
||||
public class WireFormatTest extends TestCase {
|
||||
public void testSerialization() throws Exception {
|
||||
TestAllTypes message = TestUtil.getAllSet();
|
||||
|
||||
byte[] rawBytes = message.toUnframedByteArray();
|
||||
assertEquals(rawBytes.length, message.serializedSizeUnframed());
|
||||
|
||||
TestAllTypes message2 = TestAllTypes.parseUnframed(rawBytes);
|
||||
|
||||
TestUtil.assertAllFieldsSet(message2);
|
||||
}
|
||||
|
||||
private void assertFieldsInOrder(Buffer data) throws Exception {
|
||||
try(CodedInputStream input = new CodedInputStream(data)) {
|
||||
int previousTag = 0;
|
||||
|
||||
while (true) {
|
||||
int tag = input.readTag();
|
||||
if (tag == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
assertTrue(tag > previousTag);
|
||||
input.skipField(tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc.
|
||||
// http://code.google.com/p/protobuf/
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Author: kenton@google.com (Kenton Varda)
|
||||
//
|
||||
// A proto file which tests the java_multiple_files option.
|
||||
|
||||
|
||||
import "google/protobuf/unittest.proto";
|
||||
|
||||
package protobuf_unittest;
|
||||
|
||||
option java_multiple_files = true;
|
||||
option java_outer_classname = "MultipleFilesTestProto";
|
||||
|
||||
message MessageWithNoOuter {
|
||||
message NestedMessage {
|
||||
optional int32 i = 1;
|
||||
}
|
||||
enum NestedEnum {
|
||||
BAZ = 3;
|
||||
}
|
||||
optional NestedMessage nested = 1;
|
||||
repeated TestAllTypes foreign = 2;
|
||||
optional NestedEnum nested_enum = 3;
|
||||
optional EnumWithNoOuter foreign_enum = 4;
|
||||
}
|
||||
|
||||
enum EnumWithNoOuter {
|
||||
FOO = 1;
|
||||
BAR = 2;
|
||||
}
|
||||
|
||||
service ServiceWithNoOuter {
|
||||
rpc Foo(MessageWithNoOuter) returns(TestAllTypes);
|
||||
}
|
||||
|
||||
extend TestAllExtensions {
|
||||
optional int32 extension_with_outer = 1234567;
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.activemq.protobuf;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.apache.activemq.protobuf.DeferredUnmarshal.Bar;
|
||||
import org.apache.activemq.protobuf.DeferredUnmarshal.Foo;
|
||||
|
||||
public class DeferredUnmarshalTest extends TestCase {
|
||||
|
||||
public void testDeferredDecoding() throws InvalidProtocolBufferException {
|
||||
|
||||
Foo foo = new Foo();
|
||||
foo.setField1(5);
|
||||
foo.setField2(20);
|
||||
|
||||
Bar bar = new Bar();
|
||||
|
||||
// There is no decoding pending so its' considered decoded.
|
||||
assertTrue(bar.isDecoded());
|
||||
|
||||
bar.setField1(25);
|
||||
bar.setField2(220);
|
||||
bar.setField3(foo);
|
||||
|
||||
// The message should not be encoded yet.
|
||||
assertFalse(bar.isEncoded());
|
||||
|
||||
// The message should be encoded now..
|
||||
byte[] encodedForm = bar.toUnframedByteArray();
|
||||
assertTrue(bar.isEncoded());
|
||||
|
||||
// Repeated encoding operations should just give back the same byte[]
|
||||
assertTrue(encodedForm == bar.toUnframedByteArray());
|
||||
|
||||
// Decoding does not occur until a field is accessed. The new message should
|
||||
// still be considered encoded.
|
||||
Bar bar2 = Bar.parseUnframed(encodedForm);
|
||||
assertTrue(bar2.isEncoded());
|
||||
assertFalse(bar2.isDecoded());
|
||||
|
||||
// This should now decode the message.
|
||||
assertEquals(25, bar2.getField1());
|
||||
assertTrue(bar2.isDecoded());
|
||||
|
||||
// Since bar2 still has not been modified it should still spit out the same
|
||||
// byte[]
|
||||
assertTrue(encodedForm == bar2.toUnframedByteArray());
|
||||
|
||||
// Nested messages should remain un-decoded.
|
||||
assertFalse(bar2.getField3().isDecoded());
|
||||
|
||||
// Changing a field should remove the encoding.
|
||||
bar2.setField1(35);
|
||||
assertFalse(bar2.isEncoded());
|
||||
assertTrue(bar2.isDecoded());
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.activemq.protobuf;
|
||||
|
||||
import org.apache.activemq.protobuf.DeferredUnmarshal.Bar;
|
||||
import org.apache.activemq.protobuf.DeferredUnmarshal.Foo;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class EqualsTest extends TestCase {
|
||||
|
||||
public void testDeferredUnmarshal() {
|
||||
|
||||
Bar bar1 = createBar();
|
||||
Bar bar2 = createBar();
|
||||
|
||||
// They should have the same hash and equal the same value.
|
||||
assertTrue(bar1.hashCode() == bar2.hashCode());
|
||||
assertTrue(bar1.equals(bar2));
|
||||
|
||||
// Change bar2 a little.
|
||||
|
||||
bar2.setField2(35);
|
||||
|
||||
assertFalse(bar1.hashCode() == bar2.hashCode());
|
||||
assertFalse(bar1.equals(bar2));
|
||||
|
||||
}
|
||||
|
||||
private Bar createBar() {
|
||||
Bar bar;
|
||||
Foo foo = new Foo();
|
||||
foo.setField1(5);
|
||||
foo.setField2(20);
|
||||
|
||||
bar = new Bar();
|
||||
bar.setField1(25);
|
||||
bar.setField2(220);
|
||||
bar.setField3(foo);
|
||||
return bar;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
=======================================================================
|
||||
The AcitveMQ Protocol Buffers Java Implementation
|
||||
=======================================================================
|
||||
|
||||
Protocol Buffers is a data interchange format developed by
|
||||
Google. You can get more information about Protocol Buffers
|
||||
at:
|
||||
|
||||
http://code.google.com/apis/protocolbuffers/
|
||||
|
||||
|
||||
Unfortunately the the main Protocol Buffer's project made the
|
||||
Java API cumbersome to use since the messages are immutable. They
|
||||
Justify this decision by highlighting the fact it reduces end user
|
||||
error that occur with Mutable messages.
|
||||
|
||||
This module brings you a slimmed down lean and mean API to accessing
|
||||
Protocol Buffer data structures. It provides little protection
|
||||
from end users 'hurting themselves', but it does give power user
|
||||
and easier to use API.
|
||||
|
||||
In addition, this module provides a Java based code generator so
|
||||
that it's easier to code generate your Protocol Buffer classes in
|
||||
a java based build system like Ant or Maven.
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.apache.activemq</groupId>
|
||||
<artifactId>activemq-parent</artifactId>
|
||||
<version>6.1.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<groupId>org.apache.activemq.protobuf</groupId>
|
||||
<artifactId>activemq-protobuf</artifactId>
|
||||
<packaging>maven-plugin</packaging>
|
||||
|
||||
<name>ActiveMQ :: Protocol Buffers and Compiler</name>
|
||||
|
||||
<description>
|
||||
A Simpler Protocol Buffer Java API. Includes a Proto to Java compiler.
|
||||
</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-plugin-api</artifactId>
|
||||
<version>${maven-core-version}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-core</artifactId>
|
||||
<version>${maven-core-version}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-plugin-plugin</artifactId>
|
||||
<configuration>
|
||||
<goalPrefix>amqprotobuf</goalPrefix>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>**/*Test.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>javacc-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>javacc</id>
|
||||
<goals>
|
||||
<goal>javacc</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,91 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.activemq.protobuf;
|
||||
|
||||
|
||||
final public class AsciiBuffer extends Buffer {
|
||||
|
||||
private int hashCode;
|
||||
|
||||
public AsciiBuffer(Buffer other) {
|
||||
super(other);
|
||||
}
|
||||
|
||||
public AsciiBuffer(byte[] data, int offset, int length) {
|
||||
super(data, offset, length);
|
||||
}
|
||||
|
||||
public AsciiBuffer(byte[] data) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
public AsciiBuffer(String input) {
|
||||
super(encode(input));
|
||||
}
|
||||
|
||||
public AsciiBuffer compact() {
|
||||
if (length != data.length) {
|
||||
return new AsciiBuffer(toByteArray());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return decode(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if( obj==this )
|
||||
return true;
|
||||
|
||||
if( obj==null || obj.getClass()!=AsciiBuffer.class )
|
||||
return false;
|
||||
|
||||
return equals((Buffer)obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
if( hashCode==0 ) {
|
||||
hashCode = super.hashCode();;
|
||||
}
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
static public byte[] encode(String value)
|
||||
{
|
||||
int size = value.length();
|
||||
byte rc[] = new byte[size];
|
||||
for( int i=0; i < size; i++ ) {
|
||||
rc[i] = (byte)(value.charAt(i)&0xFF);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
static public String decode(Buffer value)
|
||||
{
|
||||
int size = value.getLength();
|
||||
char rc[] = new char[size];
|
||||
for( int i=0; i < size; i++ ) {
|
||||
rc[i] = (char)(value.byteAt(i) & 0xFF );
|
||||
}
|
||||
return new String(rc);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,334 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.activemq.protobuf;
|
||||
|
||||
import static org.apache.activemq.protobuf.WireFormat.WIRETYPE_END_GROUP;
|
||||
import static org.apache.activemq.protobuf.WireFormat.WIRETYPE_LENGTH_DELIMITED;
|
||||
import static org.apache.activemq.protobuf.WireFormat.WIRETYPE_START_GROUP;
|
||||
import static org.apache.activemq.protobuf.WireFormat.makeTag;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
abstract public class BaseMessage<T> implements Message<T> {
|
||||
|
||||
protected int memoizedSerializedSize = -1;
|
||||
|
||||
abstract public T clone() throws CloneNotSupportedException;
|
||||
|
||||
public void clear() {
|
||||
memoizedSerializedSize = -1;
|
||||
}
|
||||
|
||||
public boolean isInitialized() {
|
||||
return missingFields().isEmpty();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public T assertInitialized() throws UninitializedMessageException {
|
||||
java.util.ArrayList<String> missingFields = missingFields();
|
||||
if (!missingFields.isEmpty()) {
|
||||
throw new UninitializedMessageException(missingFields);
|
||||
}
|
||||
return getThis();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected T checktInitialized() throws InvalidProtocolBufferException {
|
||||
java.util.ArrayList<String> missingFields = missingFields();
|
||||
if (!missingFields.isEmpty()) {
|
||||
throw new UninitializedMessageException(missingFields).asInvalidProtocolBufferException();
|
||||
}
|
||||
return getThis();
|
||||
}
|
||||
|
||||
public ArrayList<String> missingFields() {
|
||||
load();
|
||||
return new ArrayList<String>();
|
||||
}
|
||||
|
||||
protected void loadAndClear() {
|
||||
memoizedSerializedSize = -1;
|
||||
}
|
||||
|
||||
protected void load() {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public T mergeFrom(T other) {
|
||||
return getThis();
|
||||
}
|
||||
|
||||
public void writeUnframed(CodedOutputStream output) throws java.io.IOException {
|
||||
// if (encodedForm == null) {
|
||||
// encodedForm = new byte[serializedSizeUnframed()];
|
||||
// com.google.protobuf.CodedOutputStream original = output;
|
||||
// output =
|
||||
// com.google.protobuf.CodedOutputStream.newInstance(encodedForm);
|
||||
// if (hasField1()) {
|
||||
// output.writeInt32(1, getField1());
|
||||
// }
|
||||
// if (hasField2()) {
|
||||
// output.writeInt64(2, getField2());
|
||||
// }
|
||||
// if (hasField3()) {
|
||||
// writeMessage(output, 3, getField3());
|
||||
// }
|
||||
// output.checkNoSpaceLeft();
|
||||
// output = original;
|
||||
// }
|
||||
// output.writeRawBytes(encodedForm);
|
||||
}
|
||||
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// Write related helpers.
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
|
||||
public void writeFramed(CodedOutputStream output) throws IOException {
|
||||
output.writeRawVarint32(serializedSizeUnframed());
|
||||
writeUnframed(output);
|
||||
}
|
||||
|
||||
public Buffer toUnframedBuffer() {
|
||||
try {
|
||||
int size = serializedSizeUnframed();
|
||||
BufferOutputStream baos = new BufferOutputStream(size);
|
||||
CodedOutputStream output = new CodedOutputStream(baos);
|
||||
writeUnframed(output);
|
||||
Buffer rc = baos.toBuffer();
|
||||
if( rc.length != size ) {
|
||||
throw new IllegalStateException("Did not write as much data as expected.");
|
||||
}
|
||||
return rc;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Serializing to a byte array threw an IOException " + "(should never happen).", e);
|
||||
}
|
||||
}
|
||||
|
||||
public Buffer toFramedBuffer() {
|
||||
try {
|
||||
int size = serializedSizeFramed();
|
||||
BufferOutputStream baos = new BufferOutputStream(size);
|
||||
CodedOutputStream output = new CodedOutputStream(baos);
|
||||
writeFramed(output);
|
||||
Buffer rc = baos.toBuffer();
|
||||
if( rc.length != size ) {
|
||||
throw new IllegalStateException("Did not write as much data as expected.");
|
||||
}
|
||||
return rc;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Serializing to a byte array threw an IOException " + "(should never happen).", e);
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] toUnframedByteArray() {
|
||||
return toUnframedBuffer().toByteArray();
|
||||
}
|
||||
|
||||
public byte[] toFramedByteArray() {
|
||||
return toFramedBuffer().toByteArray();
|
||||
}
|
||||
|
||||
public void writeFramed(OutputStream output) throws IOException {
|
||||
CodedOutputStream codedOutput = new CodedOutputStream(output);
|
||||
writeFramed(codedOutput);
|
||||
codedOutput.flush();
|
||||
}
|
||||
|
||||
public void writeUnframed(OutputStream output) throws IOException {
|
||||
CodedOutputStream codedOutput = new CodedOutputStream(output);
|
||||
writeUnframed(codedOutput);
|
||||
codedOutput.flush();
|
||||
}
|
||||
|
||||
public int serializedSizeFramed() {
|
||||
int t = serializedSizeUnframed();
|
||||
return CodedOutputStream.computeRawVarint32Size(t) + t;
|
||||
|
||||
}
|
||||
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// Read related helpers.
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
|
||||
public T mergeFramed(CodedInputStream input) throws IOException {
|
||||
int length = input.readRawVarint32();
|
||||
int oldLimit = input.pushLimit(length);
|
||||
T rc = mergeUnframed(input);
|
||||
input.checkLastTagWas(0);
|
||||
input.popLimit(oldLimit);
|
||||
return rc;
|
||||
}
|
||||
|
||||
public T mergeUnframed(Buffer data) throws InvalidProtocolBufferException {
|
||||
try {
|
||||
CodedInputStream input = new CodedInputStream(data);
|
||||
mergeUnframed(input);
|
||||
input.checkLastTagWas(0);
|
||||
return getThis();
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
throw e;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("An IOException was thrown (should never happen in this method).", e);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private T getThis() {
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public T mergeFramed(Buffer data) throws InvalidProtocolBufferException {
|
||||
try {
|
||||
CodedInputStream input = new CodedInputStream(data);
|
||||
mergeFramed(input);
|
||||
input.checkLastTagWas(0);
|
||||
return getThis();
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
throw e;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("An IOException was thrown (should never happen in this method).", e);
|
||||
}
|
||||
}
|
||||
|
||||
public T mergeUnframed(byte[] data) throws InvalidProtocolBufferException {
|
||||
return mergeUnframed(new Buffer(data));
|
||||
}
|
||||
|
||||
public T mergeFramed(byte[] data) throws InvalidProtocolBufferException {
|
||||
return mergeFramed(new Buffer(data));
|
||||
}
|
||||
|
||||
public T mergeUnframed(InputStream input) throws IOException {
|
||||
CodedInputStream codedInput = new CodedInputStream(input);
|
||||
mergeUnframed(codedInput);
|
||||
return getThis();
|
||||
}
|
||||
|
||||
public T mergeFramed(InputStream input) throws IOException {
|
||||
int length = readRawVarint32(input);
|
||||
byte[] data = new byte[length];
|
||||
int pos = 0;
|
||||
while (pos < length) {
|
||||
int r = input.read(data, pos, length - pos);
|
||||
if (r < 0) {
|
||||
throw new InvalidProtocolBufferException("Input stream ended before a full message frame could be read.");
|
||||
}
|
||||
pos += r;
|
||||
}
|
||||
return mergeUnframed(data);
|
||||
}
|
||||
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
// Internal implementation methods.
|
||||
// /////////////////////////////////////////////////////////////////
|
||||
static protected <T> void addAll(Iterable<T> values, Collection<? super T> list) {
|
||||
if (values instanceof Collection) {
|
||||
@SuppressWarnings("unsafe")
|
||||
Collection<T> collection = (Collection<T>) values;
|
||||
list.addAll(collection);
|
||||
} else {
|
||||
for (T value : values) {
|
||||
list.add(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static protected void writeGroup(CodedOutputStream output, int tag, BaseMessage message) throws IOException {
|
||||
output.writeTag(tag, WIRETYPE_START_GROUP);
|
||||
message.writeUnframed(output);
|
||||
output.writeTag(tag, WIRETYPE_END_GROUP);
|
||||
}
|
||||
|
||||
static protected <T extends BaseMessage> T readGroup(CodedInputStream input, int tag, T group) throws IOException {
|
||||
group.mergeUnframed(input);
|
||||
input.checkLastTagWas(makeTag(tag, WIRETYPE_END_GROUP));
|
||||
return group;
|
||||
}
|
||||
|
||||
static protected int computeGroupSize(int tag, BaseMessage message) {
|
||||
return CodedOutputStream.computeTagSize(tag) * 2 + message.serializedSizeUnframed();
|
||||
}
|
||||
|
||||
static protected void writeMessage(CodedOutputStream output, int tag, BaseMessage message) throws IOException {
|
||||
output.writeTag(tag, WIRETYPE_LENGTH_DELIMITED);
|
||||
message.writeFramed(output);
|
||||
}
|
||||
|
||||
static protected int computeMessageSize(int tag, BaseMessage message) {
|
||||
return CodedOutputStream.computeTagSize(tag) + message.serializedSizeFramed();
|
||||
}
|
||||
|
||||
protected List<String> prefix(List<String> missingFields, String prefix) {
|
||||
ArrayList<String> rc = new ArrayList<String>(missingFields.size());
|
||||
for (String v : missingFields) {
|
||||
rc.add(prefix + v);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a raw Varint from the stream. If larger than 32 bits, discard the
|
||||
* upper bits.
|
||||
*/
|
||||
static public int readRawVarint32(InputStream is) throws IOException {
|
||||
byte tmp = readRawByte(is);
|
||||
if (tmp >= 0) {
|
||||
return tmp;
|
||||
}
|
||||
int result = tmp & 0x7f;
|
||||
if ((tmp = readRawByte(is)) >= 0) {
|
||||
result |= tmp << 7;
|
||||
} else {
|
||||
result |= (tmp & 0x7f) << 7;
|
||||
if ((tmp = readRawByte(is)) >= 0) {
|
||||
result |= tmp << 14;
|
||||
} else {
|
||||
result |= (tmp & 0x7f) << 14;
|
||||
if ((tmp = readRawByte(is)) >= 0) {
|
||||
result |= tmp << 21;
|
||||
} else {
|
||||
result |= (tmp & 0x7f) << 21;
|
||||
result |= (tmp = readRawByte(is)) << 28;
|
||||
if (tmp < 0) {
|
||||
// Discard upper 32 bits.
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if (readRawByte(is) >= 0)
|
||||
return result;
|
||||
}
|
||||
throw new InvalidProtocolBufferException("CodedInputStream encountered a malformed varint.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static protected byte readRawByte(InputStream is) throws IOException {
|
||||
int rc = is.read();
|
||||
if (rc == -1) {
|
||||
throw new InvalidProtocolBufferException("While parsing a protocol message, the input ended unexpectedly " + "in the middle of a field. This could mean either than the " + "input has been truncated or that an embedded message "
|
||||
+ "misreported its own length.");
|
||||
}
|
||||
return (byte) rc;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,211 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.activemq.protobuf;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Buffer implements Comparable<Buffer> {
|
||||
|
||||
final public byte[] data;
|
||||
final public int offset;
|
||||
final public int length;
|
||||
|
||||
public Buffer(Buffer other) {
|
||||
this(other.data, other.offset, other.length);
|
||||
}
|
||||
|
||||
public Buffer(byte data[]) {
|
||||
this(data, 0, data.length);
|
||||
}
|
||||
|
||||
public Buffer(byte data[], int offset, int length) {
|
||||
this.data = data;
|
||||
this.offset = offset;
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public Buffer(String value) {
|
||||
this(UTF8Buffer.encode(value));
|
||||
}
|
||||
|
||||
public final Buffer slice(int low, int high) {
|
||||
int sz;
|
||||
|
||||
if (high < 0) {
|
||||
sz = length + high;
|
||||
} else {
|
||||
sz = high - low;
|
||||
}
|
||||
|
||||
if (sz < 0) {
|
||||
sz = 0;
|
||||
}
|
||||
|
||||
return new Buffer(data, offset + low, sz);
|
||||
}
|
||||
|
||||
public final byte[] getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public final int getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
public final int getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
public Buffer compact() {
|
||||
if (length != data.length) {
|
||||
return new Buffer(toByteArray());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
final public byte[] toByteArray() {
|
||||
byte[] data = this.data;
|
||||
int length = this.length;
|
||||
if (length != data.length) {
|
||||
byte t[] = new byte[length];
|
||||
System.arraycopy(data, offset, t, 0, length);
|
||||
data = t;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
public byte byteAt(int i) {
|
||||
return data[offset + i];
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
byte[] target = new byte[4];
|
||||
for (int i = 0; i < length; i++) {
|
||||
target[i % 4] ^= data[offset + i];
|
||||
}
|
||||
return target[0] << 24 | target[1] << 16 | target[2] << 8 | target[3];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this)
|
||||
return true;
|
||||
|
||||
if (obj == null || obj.getClass() != Buffer.class)
|
||||
return false;
|
||||
|
||||
return equals((Buffer) obj);
|
||||
}
|
||||
|
||||
final public boolean equals(Buffer obj) {
|
||||
if (length != obj.length) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (obj.data[obj.offset + i] != data[offset + i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
final public BufferInputStream newInput() {
|
||||
return new BufferInputStream(this);
|
||||
}
|
||||
|
||||
final public BufferOutputStream newOutput() {
|
||||
return new BufferOutputStream(this);
|
||||
}
|
||||
|
||||
final public boolean isEmpty() {
|
||||
return length == 0;
|
||||
}
|
||||
|
||||
final public boolean contains(byte value) {
|
||||
return indexOf(value, 0) >= 0;
|
||||
}
|
||||
|
||||
final public int indexOf(byte value, int pos) {
|
||||
for (int i = pos; i < length; i++) {
|
||||
if (data[offset + i] == value) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
final public static Buffer join(List<Buffer> items, Buffer seperator) {
|
||||
if (items.isEmpty())
|
||||
return new Buffer(seperator.data, 0, 0);
|
||||
|
||||
int size = 0;
|
||||
for (Buffer item : items) {
|
||||
size += item.length;
|
||||
}
|
||||
size += seperator.length * (items.size() - 1);
|
||||
|
||||
int pos = 0;
|
||||
byte data[] = new byte[size];
|
||||
for (Buffer item : items) {
|
||||
if (pos != 0) {
|
||||
System.arraycopy(seperator.data, seperator.offset, data, pos, seperator.length);
|
||||
pos += seperator.length;
|
||||
}
|
||||
System.arraycopy(item.data, item.offset, data, pos, item.length);
|
||||
pos += item.length;
|
||||
}
|
||||
|
||||
return new Buffer(data, 0, size);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public String toStringUtf8() {
|
||||
return UTF8Buffer.decode(this);
|
||||
}
|
||||
|
||||
public int compareTo(Buffer o) {
|
||||
int minLength = Math.min(length, o.length);
|
||||
if (offset == o.offset) {
|
||||
int pos = offset;
|
||||
int limit = minLength + offset;
|
||||
while (pos < limit) {
|
||||
byte b1 = data[pos];
|
||||
byte b2 = o.data[pos];
|
||||
if (b1 != b2) {
|
||||
return b1 - b2;
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
} else {
|
||||
int offset1 = offset;
|
||||
int offset2 = o.offset;
|
||||
while ( minLength-- != 0) {
|
||||
byte b1 = data[offset1++];
|
||||
byte b2 = o.data[offset2++];
|
||||
if (b1 != b2) {
|
||||
return b1 - b2;
|
||||
}
|
||||
}
|
||||
}
|
||||
return length - o.length;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.activemq.protobuf;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Very similar to the java.io.ByteArrayInputStream but this version is not
|
||||
* thread safe.
|
||||
*/
|
||||
final public class BufferInputStream extends InputStream {
|
||||
|
||||
byte buffer[];
|
||||
int limit;
|
||||
int pos;
|
||||
int mark;
|
||||
|
||||
public BufferInputStream(byte data[]) {
|
||||
this(data, 0, data.length);
|
||||
}
|
||||
|
||||
public BufferInputStream(Buffer sequence) {
|
||||
this(sequence.getData(), sequence.getOffset(), sequence.getLength());
|
||||
}
|
||||
|
||||
public BufferInputStream(byte data[], int offset, int size) {
|
||||
this.buffer = data;
|
||||
this.mark = offset;
|
||||
this.pos = offset;
|
||||
this.limit = offset + size;
|
||||
}
|
||||
|
||||
public int read() throws IOException {
|
||||
if (pos < limit) {
|
||||
return buffer[pos++] & 0xff;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public int read(byte[] b) throws IOException {
|
||||
return read(b, 0, b.length);
|
||||
}
|
||||
|
||||
public int read(byte b[], int off, int len) {
|
||||
if (pos < limit) {
|
||||
len = Math.min(len, limit - pos);
|
||||
System.arraycopy(buffer, pos, b, off, len);
|
||||
pos += len;
|
||||
return len;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public Buffer readBuffer(int len) {
|
||||
Buffer rc=null;
|
||||
if (pos < limit) {
|
||||
len = Math.min(len, limit - pos);
|
||||
rc = new Buffer(buffer, pos, len);
|
||||
pos += len;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
public long skip(long len) throws IOException {
|
||||
if (pos < limit) {
|
||||
len = Math.min(len, limit - pos);
|
||||
if (len > 0) {
|
||||
pos += len;
|
||||
}
|
||||
return len;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public int available() {
|
||||
return limit - pos;
|
||||
}
|
||||
|
||||
public boolean markSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void mark(int markpos) {
|
||||
mark = pos;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
pos = mark;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.activemq.protobuf;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
|
||||
/**
|
||||
* Very similar to the java.io.ByteArrayOutputStream but this version
|
||||
* is not thread safe and the resulting data is returned in a Buffer
|
||||
* to avoid an extra byte[] allocation. It also does not re-grow it's
|
||||
* internal buffer.
|
||||
*/
|
||||
final public class BufferOutputStream extends OutputStream {
|
||||
|
||||
byte buffer[];
|
||||
int offset;
|
||||
int limit;
|
||||
int pos;
|
||||
|
||||
public BufferOutputStream(int size) {
|
||||
this(new byte[size]);
|
||||
}
|
||||
|
||||
public BufferOutputStream(byte[] buffer) {
|
||||
this.buffer = buffer;
|
||||
this.limit = buffer.length;
|
||||
}
|
||||
|
||||
public BufferOutputStream(Buffer data) {
|
||||
this.buffer = data.data;
|
||||
this.pos = this.offset = data.offset;
|
||||
this.limit = data.offset+data.length;
|
||||
}
|
||||
|
||||
|
||||
public void write(int b) throws IOException {
|
||||
int newPos = pos + 1;
|
||||
checkCapacity(newPos);
|
||||
buffer[pos] = (byte) b;
|
||||
pos = newPos;
|
||||
}
|
||||
|
||||
public void write(byte b[], int off, int len) throws IOException {
|
||||
int newPos = pos + len;
|
||||
checkCapacity(newPos);
|
||||
System.arraycopy(b, off, buffer, pos, len);
|
||||
pos = newPos;
|
||||
}
|
||||
|
||||
public Buffer getNextBuffer(int len) throws IOException {
|
||||
int newPos = pos + len;
|
||||
checkCapacity(newPos);
|
||||
return new Buffer(buffer, pos, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures the the buffer has at least the minimumCapacity specified.
|
||||
* @param i
|
||||
* @throws EOFException
|
||||
*/
|
||||
private void checkCapacity(int minimumCapacity) throws IOException {
|
||||
if( minimumCapacity > limit ) {
|
||||
throw new EOFException("Buffer limit reached.");
|
||||
}
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
pos = offset;
|
||||
}
|
||||
|
||||
public Buffer toBuffer() {
|
||||
return new Buffer(buffer, offset, pos);
|
||||
}
|
||||
|
||||
public byte[] toByteArray() {
|
||||
return toBuffer().toByteArray();
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return offset-pos;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,418 @@
|
|||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc.
|
||||
// http://code.google.com/p/protobuf/
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package org.apache.activemq.protobuf;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.FilterInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Reads and decodes protocol message fields.
|
||||
*
|
||||
* This class contains two kinds of methods: methods that read specific protocol
|
||||
* message constructs and field types (e.g. {@link #readTag()} and
|
||||
* {@link #readInt32()}) and methods that read low-level values (e.g.
|
||||
* {@link #readRawVarint32()} and {@link #readRawBytes}). If you are reading
|
||||
* encoded protocol messages, you should use the former methods, but if you are
|
||||
* reading some other format of your own design, use the latter.
|
||||
*
|
||||
* @author kenton@google.com Kenton Varda
|
||||
*/
|
||||
public final class CodedInputStream extends FilterInputStream {
|
||||
|
||||
private int lastTag = 0;
|
||||
private int limit = Integer.MAX_VALUE;
|
||||
private int pos;
|
||||
private BufferInputStream bis;
|
||||
|
||||
public CodedInputStream(InputStream in) {
|
||||
super(in);
|
||||
if( in.getClass() == BufferInputStream.class ) {
|
||||
bis = (BufferInputStream)in;
|
||||
}
|
||||
}
|
||||
|
||||
public CodedInputStream(Buffer data) {
|
||||
this(new BufferInputStream(data));
|
||||
limit = data.length;
|
||||
}
|
||||
|
||||
public CodedInputStream(byte[] data) {
|
||||
this(new BufferInputStream(data));
|
||||
limit = data.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to read a field tag, returning zero if we have reached EOF.
|
||||
* Protocol message parsers use this to read tags, since a protocol message
|
||||
* may legally end wherever a tag occurs, and zero is not a valid tag
|
||||
* number.
|
||||
*/
|
||||
public int readTag() throws IOException {
|
||||
if( pos >= limit ) {
|
||||
lastTag=0;
|
||||
return 0;
|
||||
}
|
||||
try {
|
||||
lastTag = readRawVarint32();
|
||||
if (lastTag == 0) {
|
||||
// If we actually read zero, that's not a valid tag.
|
||||
throw InvalidProtocolBufferException.invalidTag();
|
||||
}
|
||||
return lastTag;
|
||||
} catch (EOFException e) {
|
||||
lastTag=0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Verifies that the last call to readTag() returned the given tag value.
|
||||
* This is used to verify that a nested group ended with the correct end
|
||||
* tag.
|
||||
*
|
||||
* @throws InvalidProtocolBufferException
|
||||
* {@code value} does not match the last tag.
|
||||
*/
|
||||
public void checkLastTagWas(int value) throws InvalidProtocolBufferException {
|
||||
if (lastTag != value) {
|
||||
throw InvalidProtocolBufferException.invalidEndTag();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads and discards a single field, given its tag value.
|
||||
*
|
||||
* @return {@code false} if the tag is an endgroup tag, in which case
|
||||
* nothing is skipped. Otherwise, returns {@code true}.
|
||||
*/
|
||||
public boolean skipField(int tag) throws IOException {
|
||||
switch (WireFormat.getTagWireType(tag)) {
|
||||
case WireFormat.WIRETYPE_VARINT:
|
||||
readInt32();
|
||||
return true;
|
||||
case WireFormat.WIRETYPE_FIXED64:
|
||||
readRawLittleEndian64();
|
||||
return true;
|
||||
case WireFormat.WIRETYPE_LENGTH_DELIMITED:
|
||||
skipRawBytes(readRawVarint32());
|
||||
return true;
|
||||
case WireFormat.WIRETYPE_START_GROUP:
|
||||
skipMessage();
|
||||
checkLastTagWas(WireFormat.makeTag(WireFormat.getTagFieldNumber(tag), WireFormat.WIRETYPE_END_GROUP));
|
||||
return true;
|
||||
case WireFormat.WIRETYPE_END_GROUP:
|
||||
return false;
|
||||
case WireFormat.WIRETYPE_FIXED32:
|
||||
readRawLittleEndian32();
|
||||
return true;
|
||||
default:
|
||||
throw InvalidProtocolBufferException.invalidWireType();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads and discards an entire message. This will read either until EOF or
|
||||
* until an endgroup tag, whichever comes first.
|
||||
*/
|
||||
public void skipMessage() throws IOException {
|
||||
while (true) {
|
||||
int tag = readTag();
|
||||
if (tag == 0 || !skipField(tag))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
/** Read a {@code double} field value from the stream. */
|
||||
public double readDouble() throws IOException {
|
||||
return Double.longBitsToDouble(readRawLittleEndian64());
|
||||
}
|
||||
|
||||
/** Read a {@code float} field value from the stream. */
|
||||
public float readFloat() throws IOException {
|
||||
return Float.intBitsToFloat(readRawLittleEndian32());
|
||||
}
|
||||
|
||||
/** Read a {@code uint64} field value from the stream. */
|
||||
public long readUInt64() throws IOException {
|
||||
return readRawVarint64();
|
||||
}
|
||||
|
||||
/** Read an {@code int64} field value from the stream. */
|
||||
public long readInt64() throws IOException {
|
||||
return readRawVarint64();
|
||||
}
|
||||
|
||||
/** Read an {@code int32} field value from the stream. */
|
||||
public int readInt32() throws IOException {
|
||||
return readRawVarint32();
|
||||
}
|
||||
|
||||
/** Read a {@code fixed64} field value from the stream. */
|
||||
public long readFixed64() throws IOException {
|
||||
return readRawLittleEndian64();
|
||||
}
|
||||
|
||||
/** Read a {@code fixed32} field value from the stream. */
|
||||
public int readFixed32() throws IOException {
|
||||
return readRawLittleEndian32();
|
||||
}
|
||||
|
||||
/** Read a {@code bool} field value from the stream. */
|
||||
public boolean readBool() throws IOException {
|
||||
return readRawVarint32() != 0;
|
||||
}
|
||||
|
||||
/** Read a {@code string} field value from the stream. */
|
||||
public String readString() throws IOException {
|
||||
int size = readRawVarint32();
|
||||
Buffer data = readRawBytes(size);
|
||||
return new String(data.data, data.offset, data.length, "UTF-8");
|
||||
}
|
||||
|
||||
/** Read a {@code bytes} field value from the stream. */
|
||||
public Buffer readBytes() throws IOException {
|
||||
int size = readRawVarint32();
|
||||
return readRawBytes(size);
|
||||
}
|
||||
|
||||
/** Read a {@code uint32} field value from the stream. */
|
||||
public int readUInt32() throws IOException {
|
||||
return readRawVarint32();
|
||||
}
|
||||
|
||||
/**
|
||||
* Read an enum field value from the stream. Caller is responsible for
|
||||
* converting the numeric value to an actual enum.
|
||||
*/
|
||||
public int readEnum() throws IOException {
|
||||
return readRawVarint32();
|
||||
}
|
||||
|
||||
/** Read an {@code sfixed32} field value from the stream. */
|
||||
public int readSFixed32() throws IOException {
|
||||
return readRawLittleEndian32();
|
||||
}
|
||||
|
||||
/** Read an {@code sfixed64} field value from the stream. */
|
||||
public long readSFixed64() throws IOException {
|
||||
return readRawLittleEndian64();
|
||||
}
|
||||
|
||||
/** Read an {@code sint32} field value from the stream. */
|
||||
public int readSInt32() throws IOException {
|
||||
return decodeZigZag32(readRawVarint32());
|
||||
}
|
||||
|
||||
/** Read an {@code sint64} field value from the stream. */
|
||||
public long readSInt64() throws IOException {
|
||||
return decodeZigZag64(readRawVarint64());
|
||||
}
|
||||
|
||||
// =================================================================
|
||||
|
||||
/**
|
||||
* Read a raw Varint from the stream. If larger than 32 bits, discard the
|
||||
* upper bits.
|
||||
*/
|
||||
public int readRawVarint32() throws IOException {
|
||||
byte tmp = readRawByte();
|
||||
if (tmp >= 0) {
|
||||
return tmp;
|
||||
}
|
||||
int result = tmp & 0x7f;
|
||||
if ((tmp = readRawByte()) >= 0) {
|
||||
result |= tmp << 7;
|
||||
} else {
|
||||
result |= (tmp & 0x7f) << 7;
|
||||
if ((tmp = readRawByte()) >= 0) {
|
||||
result |= tmp << 14;
|
||||
} else {
|
||||
result |= (tmp & 0x7f) << 14;
|
||||
if ((tmp = readRawByte()) >= 0) {
|
||||
result |= tmp << 21;
|
||||
} else {
|
||||
result |= (tmp & 0x7f) << 21;
|
||||
result |= (tmp = readRawByte()) << 28;
|
||||
if (tmp < 0) {
|
||||
// Discard upper 32 bits.
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if (readRawByte() >= 0)
|
||||
return result;
|
||||
}
|
||||
throw InvalidProtocolBufferException.malformedVarint();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Read a raw Varint from the stream. */
|
||||
public long readRawVarint64() throws IOException {
|
||||
int shift = 0;
|
||||
long result = 0;
|
||||
while (shift < 64) {
|
||||
byte b = readRawByte();
|
||||
result |= (long) (b & 0x7F) << shift;
|
||||
if ((b & 0x80) == 0)
|
||||
return result;
|
||||
shift += 7;
|
||||
}
|
||||
throw InvalidProtocolBufferException.malformedVarint();
|
||||
}
|
||||
|
||||
/** Read a 32-bit little-endian integer from the stream. */
|
||||
public int readRawLittleEndian32() throws IOException {
|
||||
byte b1 = readRawByte();
|
||||
byte b2 = readRawByte();
|
||||
byte b3 = readRawByte();
|
||||
byte b4 = readRawByte();
|
||||
return (((int) b1 & 0xff)) | (((int) b2 & 0xff) << 8) | (((int) b3 & 0xff) << 16) | (((int) b4 & 0xff) << 24);
|
||||
}
|
||||
|
||||
/** Read a 64-bit little-endian integer from the stream. */
|
||||
public long readRawLittleEndian64() throws IOException {
|
||||
byte b1 = readRawByte();
|
||||
byte b2 = readRawByte();
|
||||
byte b3 = readRawByte();
|
||||
byte b4 = readRawByte();
|
||||
byte b5 = readRawByte();
|
||||
byte b6 = readRawByte();
|
||||
byte b7 = readRawByte();
|
||||
byte b8 = readRawByte();
|
||||
return (((long) b1 & 0xff)) | (((long) b2 & 0xff) << 8) | (((long) b3 & 0xff) << 16) | (((long) b4 & 0xff) << 24) | (((long) b5 & 0xff) << 32) | (((long) b6 & 0xff) << 40) | (((long) b7 & 0xff) << 48) | (((long) b8 & 0xff) << 56);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a ZigZag-encoded 32-bit value. ZigZag encodes signed integers into
|
||||
* values that can be efficiently encoded with varint. (Otherwise, negative
|
||||
* values must be sign-extended to 64 bits to be varint encoded, thus always
|
||||
* taking 10 bytes on the wire.)
|
||||
*
|
||||
* @param n
|
||||
* An unsigned 32-bit integer, stored in a signed int because
|
||||
* Java has no explicit unsigned support.
|
||||
* @return A signed 32-bit integer.
|
||||
*/
|
||||
public static int decodeZigZag32(int n) {
|
||||
return (n >>> 1) ^ -(n & 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a ZigZag-encoded 64-bit value. ZigZag encodes signed integers into
|
||||
* values that can be efficiently encoded with varint. (Otherwise, negative
|
||||
* values must be sign-extended to 64 bits to be varint encoded, thus always
|
||||
* taking 10 bytes on the wire.)
|
||||
*
|
||||
* @param n
|
||||
* An unsigned 64-bit integer, stored in a signed int because
|
||||
* Java has no explicit unsigned support.
|
||||
* @return A signed 64-bit integer.
|
||||
*/
|
||||
public static long decodeZigZag64(long n) {
|
||||
return (n >>> 1) ^ -(n & 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read one byte from the input.
|
||||
*
|
||||
* @throws InvalidProtocolBufferException
|
||||
* The end of the stream or the current limit was reached.
|
||||
*/
|
||||
public byte readRawByte() throws IOException {
|
||||
if( pos >= limit ) {
|
||||
throw new EOFException();
|
||||
}
|
||||
int rc = in.read();
|
||||
if( rc < 0 ) {
|
||||
throw new EOFException();
|
||||
}
|
||||
pos++;
|
||||
return (byte)( rc & 0xFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a fixed size of bytes from the input.
|
||||
*
|
||||
* @throws InvalidProtocolBufferException
|
||||
* The end of the stream or the current limit was reached.
|
||||
*/
|
||||
public Buffer readRawBytes(int size) throws IOException {
|
||||
if( size == 0) {
|
||||
return new Buffer(new byte[]{});
|
||||
}
|
||||
if( this.pos+size > limit ) {
|
||||
throw new EOFException();
|
||||
}
|
||||
|
||||
// If the underlying stream is a ByteArrayInputStream
|
||||
// then we can avoid an array copy.
|
||||
if( bis!=null ) {
|
||||
Buffer rc = bis.readBuffer(size);
|
||||
if( rc==null || rc.getLength() < size ) {
|
||||
throw new EOFException();
|
||||
}
|
||||
this.pos += rc.getLength();
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Otherwise we, have to do it the old fasioned way
|
||||
byte[] rc = new byte[size];
|
||||
int c;
|
||||
int pos=0;
|
||||
while( pos < size ) {
|
||||
c = in.read(rc, pos, size-pos);
|
||||
if( c < 0 ) {
|
||||
throw new EOFException();
|
||||
}
|
||||
this.pos += c;
|
||||
pos += c;
|
||||
}
|
||||
|
||||
return new Buffer(rc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads and discards {@code size} bytes.
|
||||
*
|
||||
* @throws InvalidProtocolBufferException
|
||||
* The end of the stream or the current limit was reached.
|
||||
*/
|
||||
public void skipRawBytes(int size) throws IOException {
|
||||
int pos = 0;
|
||||
while (pos < size) {
|
||||
int n = (int) in.skip(size - pos);
|
||||
pos += n;
|
||||
}
|
||||
}
|
||||
|
||||
public int pushLimit(int limit) {
|
||||
int rc = this.limit;
|
||||
this.limit = pos+limit;
|
||||
return rc;
|
||||
}
|
||||
|
||||
public void popLimit(int limit) {
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,481 @@
|
|||
//Protocol Buffers - Google's data interchange format
|
||||
//Copyright 2008 Google Inc.
|
||||
//http://code.google.com/p/protobuf/
|
||||
//
|
||||
//Licensed under the Apache License, Version 2.0 (the "License");
|
||||
//you may not use this file except in compliance with the License.
|
||||
//You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
//Unless required by applicable law or agreed to in writing, software
|
||||
//distributed under the License is distributed on an "AS IS" BASIS,
|
||||
//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//See the License for the specific language governing permissions and
|
||||
//limitations under the License.
|
||||
package org.apache.activemq.protobuf;
|
||||
|
||||
import java.io.FilterOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* Encodes and writes protocol message fields.
|
||||
*
|
||||
* <p>
|
||||
* This class contains two kinds of methods: methods that write specific
|
||||
* protocol message constructs and field types (e.g. {@link #writeTag} and
|
||||
* {@link #writeInt32}) and methods that write low-level values (e.g.
|
||||
* {@link #writeRawVarint32} and {@link #writeRawBytes}). If you are writing
|
||||
* encoded protocol messages, you should use the former methods, but if you are
|
||||
* writing some other format of your own design, use the latter.
|
||||
*
|
||||
* <p>
|
||||
* This class is totally unsynchronized.
|
||||
*
|
||||
* @author kneton@google.com Kenton Varda
|
||||
*/
|
||||
public final class CodedOutputStream extends FilterOutputStream {
|
||||
|
||||
private BufferOutputStream bos;
|
||||
|
||||
public CodedOutputStream(OutputStream os) {
|
||||
super(os);
|
||||
if( os instanceof BufferOutputStream ) {
|
||||
bos = (BufferOutputStream)os;
|
||||
}
|
||||
}
|
||||
|
||||
public CodedOutputStream(byte[] data) {
|
||||
super(new BufferOutputStream(data));
|
||||
}
|
||||
|
||||
public CodedOutputStream(Buffer data) {
|
||||
super(new BufferOutputStream(data));
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
|
||||
/** Write a {@code double} field, including tag, to the stream. */
|
||||
public void writeDouble(int fieldNumber, double value) throws IOException {
|
||||
writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
|
||||
writeRawLittleEndian64(Double.doubleToRawLongBits(value));
|
||||
}
|
||||
|
||||
/** Write a {@code float} field, including tag, to the stream. */
|
||||
public void writeFloat(int fieldNumber, float value) throws IOException {
|
||||
writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
|
||||
writeRawLittleEndian32(Float.floatToRawIntBits(value));
|
||||
}
|
||||
|
||||
/** Write a {@code uint64} field, including tag, to the stream. */
|
||||
public void writeUInt64(int fieldNumber, long value) throws IOException {
|
||||
writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
|
||||
writeRawVarint64(value);
|
||||
}
|
||||
|
||||
/** Write an {@code int64} field, including tag, to the stream. */
|
||||
public void writeInt64(int fieldNumber, long value) throws IOException {
|
||||
writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
|
||||
writeRawVarint64(value);
|
||||
}
|
||||
|
||||
/** Write an {@code int32} field, including tag, to the stream. */
|
||||
public void writeInt32(int fieldNumber, int value) throws IOException {
|
||||
writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
|
||||
if (value >= 0) {
|
||||
writeRawVarint32(value);
|
||||
} else {
|
||||
// Must sign-extend.
|
||||
writeRawVarint64(value);
|
||||
}
|
||||
}
|
||||
|
||||
/** Write a {@code fixed64} field, including tag, to the stream. */
|
||||
public void writeFixed64(int fieldNumber, long value) throws IOException {
|
||||
writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
|
||||
writeRawLittleEndian64(value);
|
||||
}
|
||||
|
||||
/** Write a {@code fixed32} field, including tag, to the stream. */
|
||||
public void writeFixed32(int fieldNumber, int value) throws IOException {
|
||||
writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
|
||||
writeRawLittleEndian32(value);
|
||||
}
|
||||
|
||||
/** Write a {@code bool} field, including tag, to the stream. */
|
||||
public void writeBool(int fieldNumber, boolean value) throws IOException {
|
||||
writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
|
||||
writeRawByte(value ? 1 : 0);
|
||||
}
|
||||
|
||||
/** Write a {@code string} field, including tag, to the stream. */
|
||||
public void writeString(int fieldNumber, String value) throws IOException {
|
||||
writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
|
||||
// Unfortunately there does not appear to be any way to tell Java to
|
||||
// encode
|
||||
// UTF-8 directly into our buffer, so we have to let it create its own
|
||||
// byte
|
||||
// array and then copy.
|
||||
byte[] bytes = value.getBytes("UTF-8");
|
||||
writeRawVarint32(bytes.length);
|
||||
writeRawBytes(bytes);
|
||||
}
|
||||
|
||||
/** Write a {@code bytes} field, including tag, to the stream. */
|
||||
public void writeBytes(int fieldNumber, Buffer value) throws IOException {
|
||||
writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
|
||||
writeRawVarint32(value.length);
|
||||
writeRawBytes(value.data, value.offset, value.length);
|
||||
}
|
||||
|
||||
/** Write a {@code uint32} field, including tag, to the stream. */
|
||||
public void writeUInt32(int fieldNumber, int value) throws IOException {
|
||||
writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
|
||||
writeRawVarint32(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write an enum field, including tag, to the stream. Caller is responsible
|
||||
* for converting the enum value to its numeric value.
|
||||
*/
|
||||
public void writeEnum(int fieldNumber, int value) throws IOException {
|
||||
writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
|
||||
writeRawVarint32(value);
|
||||
}
|
||||
|
||||
/** Write an {@code sfixed32} field, including tag, to the stream. */
|
||||
public void writeSFixed32(int fieldNumber, int value) throws IOException {
|
||||
writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
|
||||
writeRawLittleEndian32(value);
|
||||
}
|
||||
|
||||
/** Write an {@code sfixed64} field, including tag, to the stream. */
|
||||
public void writeSFixed64(int fieldNumber, long value) throws IOException {
|
||||
writeTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
|
||||
writeRawLittleEndian64(value);
|
||||
}
|
||||
|
||||
/** Write an {@code sint32} field, including tag, to the stream. */
|
||||
public void writeSInt32(int fieldNumber, int value) throws IOException {
|
||||
writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
|
||||
writeRawVarint32(encodeZigZag32(value));
|
||||
}
|
||||
|
||||
/** Write an {@code sint64} field, including tag, to the stream. */
|
||||
public void writeSInt64(int fieldNumber, long value) throws IOException {
|
||||
writeTag(fieldNumber, WireFormat.WIRETYPE_VARINT);
|
||||
writeRawVarint64(encodeZigZag64(value));
|
||||
}
|
||||
|
||||
// =================================================================
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode a {@code
|
||||
* double} field, including tag.
|
||||
*/
|
||||
public static int computeDoubleSize(int fieldNumber, double value) {
|
||||
return computeTagSize(fieldNumber) + LITTLE_ENDIAN_64_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode a {@code
|
||||
* float} field, including tag.
|
||||
*/
|
||||
public static int computeFloatSize(int fieldNumber, float value) {
|
||||
return computeTagSize(fieldNumber) + LITTLE_ENDIAN_32_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode a {@code
|
||||
* uint64} field, including tag.
|
||||
*/
|
||||
public static int computeUInt64Size(int fieldNumber, long value) {
|
||||
return computeTagSize(fieldNumber) + computeRawVarint64Size(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode an {@code
|
||||
* int64} field, including tag.
|
||||
*/
|
||||
public static int computeInt64Size(int fieldNumber, long value) {
|
||||
return computeTagSize(fieldNumber) + computeRawVarint64Size(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode an {@code
|
||||
* int32} field, including tag.
|
||||
*/
|
||||
public static int computeInt32Size(int fieldNumber, int value) {
|
||||
if (value >= 0) {
|
||||
return computeTagSize(fieldNumber) + computeRawVarint32Size(value);
|
||||
} else {
|
||||
// Must sign-extend.
|
||||
return computeTagSize(fieldNumber) + 10;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode a {@code
|
||||
* fixed64} field, including tag.
|
||||
*/
|
||||
public static int computeFixed64Size(int fieldNumber, long value) {
|
||||
return computeTagSize(fieldNumber) + LITTLE_ENDIAN_64_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode a {@code
|
||||
* fixed32} field, including tag.
|
||||
*/
|
||||
public static int computeFixed32Size(int fieldNumber, int value) {
|
||||
return computeTagSize(fieldNumber) + LITTLE_ENDIAN_32_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode a {@code bool}
|
||||
* field, including tag.
|
||||
*/
|
||||
public static int computeBoolSize(int fieldNumber, boolean value) {
|
||||
return computeTagSize(fieldNumber) + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode a {@code
|
||||
* string} field, including tag.
|
||||
*/
|
||||
public static int computeStringSize(int fieldNumber, String value) {
|
||||
try {
|
||||
byte[] bytes = value.getBytes("UTF-8");
|
||||
return computeTagSize(fieldNumber) + computeRawVarint32Size(bytes.length) + bytes.length;
|
||||
} catch (java.io.UnsupportedEncodingException e) {
|
||||
throw new RuntimeException("UTF-8 not supported.", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode a {@code
|
||||
* bytes} field, including tag.
|
||||
*/
|
||||
public static int computeBytesSize(int fieldNumber, Buffer value) {
|
||||
return computeTagSize(fieldNumber) + computeRawVarint32Size(value.length) + value.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode a {@code
|
||||
* uint32} field, including tag.
|
||||
*/
|
||||
public static int computeUInt32Size(int fieldNumber, int value) {
|
||||
return computeTagSize(fieldNumber) + computeRawVarint32Size(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode an enum field,
|
||||
* including tag. Caller is responsible for converting the enum value to its
|
||||
* numeric value.
|
||||
*/
|
||||
public static int computeEnumSize(int fieldNumber, int value) {
|
||||
return computeTagSize(fieldNumber) + computeRawVarint32Size(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode an {@code
|
||||
* sfixed32} field, including tag.
|
||||
*/
|
||||
public static int computeSFixed32Size(int fieldNumber, int value) {
|
||||
return computeTagSize(fieldNumber) + LITTLE_ENDIAN_32_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode an {@code
|
||||
* sfixed64} field, including tag.
|
||||
*/
|
||||
public static int computeSFixed64Size(int fieldNumber, long value) {
|
||||
return computeTagSize(fieldNumber) + LITTLE_ENDIAN_64_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode an {@code
|
||||
* sint32} field, including tag.
|
||||
*/
|
||||
public static int computeSInt32Size(int fieldNumber, int value) {
|
||||
return computeTagSize(fieldNumber) + computeRawVarint32Size(encodeZigZag32(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode an {@code
|
||||
* sint64} field, including tag.
|
||||
*/
|
||||
public static int computeSInt64Size(int fieldNumber, long value) {
|
||||
return computeTagSize(fieldNumber) + computeRawVarint64Size(encodeZigZag64(value));
|
||||
}
|
||||
|
||||
/** Write a single byte. */
|
||||
public void writeRawByte(byte value) throws IOException {
|
||||
out.write(value);
|
||||
}
|
||||
|
||||
/** Write a single byte, represented by an integer value. */
|
||||
public void writeRawByte(int value) throws IOException {
|
||||
writeRawByte((byte) value);
|
||||
}
|
||||
|
||||
/** Write an array of bytes. */
|
||||
public void writeRawBytes(byte[] value) throws IOException {
|
||||
writeRawBytes(value, 0, value.length);
|
||||
}
|
||||
|
||||
/** Write part of an array of bytes. */
|
||||
public void writeRawBytes(byte[] value, int offset, int length) throws IOException {
|
||||
out.write(value, offset, length);
|
||||
}
|
||||
|
||||
public void writeRawBytes(Buffer data) throws IOException {
|
||||
out.write(data.data, data.offset, data.length);
|
||||
}
|
||||
|
||||
/** Encode and write a tag. */
|
||||
public void writeTag(int fieldNumber, int wireType) throws IOException {
|
||||
writeRawVarint32(WireFormat.makeTag(fieldNumber, wireType));
|
||||
}
|
||||
|
||||
/** Compute the number of bytes that would be needed to encode a tag. */
|
||||
public static int computeTagSize(int fieldNumber) {
|
||||
return computeRawVarint32Size(WireFormat.makeTag(fieldNumber, 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode and write a varint. {@code value} is treated as unsigned, so it
|
||||
* won't be sign-extended if negative.
|
||||
*/
|
||||
public void writeRawVarint32(int value) throws IOException {
|
||||
while (true) {
|
||||
if ((value & ~0x7F) == 0) {
|
||||
writeRawByte(value);
|
||||
return;
|
||||
} else {
|
||||
writeRawByte((value & 0x7F) | 0x80);
|
||||
value >>>= 7;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the number of bytes that would be needed to encode a varint.
|
||||
* {@code value} is treated as unsigned, so it won't be sign-extended if
|
||||
* negative.
|
||||
*/
|
||||
public static int computeRawVarint32Size(int value) {
|
||||
if ((value & (0xffffffff << 7)) == 0)
|
||||
return 1;
|
||||
if ((value & (0xffffffff << 14)) == 0)
|
||||
return 2;
|
||||
if ((value & (0xffffffff << 21)) == 0)
|
||||
return 3;
|
||||
if ((value & (0xffffffff << 28)) == 0)
|
||||
return 4;
|
||||
return 5;
|
||||
}
|
||||
|
||||
/** Encode and write a varint. */
|
||||
public void writeRawVarint64(long value) throws IOException {
|
||||
while (true) {
|
||||
if ((value & ~0x7FL) == 0) {
|
||||
writeRawByte((int) value);
|
||||
return;
|
||||
} else {
|
||||
writeRawByte(((int) value & 0x7F) | 0x80);
|
||||
value >>>= 7;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Compute the number of bytes that would be needed to encode a varint. */
|
||||
public static int computeRawVarint64Size(long value) {
|
||||
if ((value & (0xffffffffffffffffL << 7)) == 0)
|
||||
return 1;
|
||||
if ((value & (0xffffffffffffffffL << 14)) == 0)
|
||||
return 2;
|
||||
if ((value & (0xffffffffffffffffL << 21)) == 0)
|
||||
return 3;
|
||||
if ((value & (0xffffffffffffffffL << 28)) == 0)
|
||||
return 4;
|
||||
if ((value & (0xffffffffffffffffL << 35)) == 0)
|
||||
return 5;
|
||||
if ((value & (0xffffffffffffffffL << 42)) == 0)
|
||||
return 6;
|
||||
if ((value & (0xffffffffffffffffL << 49)) == 0)
|
||||
return 7;
|
||||
if ((value & (0xffffffffffffffffL << 56)) == 0)
|
||||
return 8;
|
||||
if ((value & (0xffffffffffffffffL << 63)) == 0)
|
||||
return 9;
|
||||
return 10;
|
||||
}
|
||||
|
||||
/** Write a little-endian 32-bit integer. */
|
||||
public void writeRawLittleEndian32(int value) throws IOException {
|
||||
writeRawByte((value) & 0xFF);
|
||||
writeRawByte((value >> 8) & 0xFF);
|
||||
writeRawByte((value >> 16) & 0xFF);
|
||||
writeRawByte((value >> 24) & 0xFF);
|
||||
}
|
||||
|
||||
public static final int LITTLE_ENDIAN_32_SIZE = 4;
|
||||
|
||||
/** Write a little-endian 64-bit integer. */
|
||||
public void writeRawLittleEndian64(long value) throws IOException {
|
||||
writeRawByte((int) (value) & 0xFF);
|
||||
writeRawByte((int) (value >> 8) & 0xFF);
|
||||
writeRawByte((int) (value >> 16) & 0xFF);
|
||||
writeRawByte((int) (value >> 24) & 0xFF);
|
||||
writeRawByte((int) (value >> 32) & 0xFF);
|
||||
writeRawByte((int) (value >> 40) & 0xFF);
|
||||
writeRawByte((int) (value >> 48) & 0xFF);
|
||||
writeRawByte((int) (value >> 56) & 0xFF);
|
||||
}
|
||||
|
||||
public static final int LITTLE_ENDIAN_64_SIZE = 8;
|
||||
|
||||
/**
|
||||
* Encode a ZigZag-encoded 32-bit value. ZigZag encodes signed integers into
|
||||
* values that can be efficiently encoded with varint. (Otherwise, negative
|
||||
* values must be sign-extended to 64 bits to be varint encoded, thus always
|
||||
* taking 10 bytes on the wire.)
|
||||
*
|
||||
* @param n
|
||||
* A signed 32-bit integer.
|
||||
* @return An unsigned 32-bit integer, stored in a signed int because Java
|
||||
* has no explicit unsigned support.
|
||||
*/
|
||||
public static int encodeZigZag32(int n) {
|
||||
// Note: the right-shift must be arithmetic
|
||||
return (n << 1) ^ (n >> 31);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode a ZigZag-encoded 64-bit value. ZigZag encodes signed integers into
|
||||
* values that can be efficiently encoded with varint. (Otherwise, negative
|
||||
* values must be sign-extended to 64 bits to be varint encoded, thus always
|
||||
* taking 10 bytes on the wire.)
|
||||
*
|
||||
* @param n
|
||||
* A signed 64-bit integer.
|
||||
* @return An unsigned 64-bit integer, stored in a signed int because Java
|
||||
* has no explicit unsigned support.
|
||||
*/
|
||||
public static long encodeZigZag64(long n) {
|
||||
// Note: the right-shift must be arithmetic
|
||||
return (n << 1) ^ (n >> 63);
|
||||
}
|
||||
|
||||
public void checkNoSpaceLeft() {
|
||||
}
|
||||
|
||||
public Buffer getNextBuffer(int size) throws IOException {
|
||||
if( bos==null ) {
|
||||
return null;
|
||||
}
|
||||
return bos.getNextBuffer(size);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.activemq.protobuf;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
abstract public class DeferredDecodeMessage<T> extends BaseMessage<T> {
|
||||
|
||||
protected Buffer encodedForm;
|
||||
protected boolean decoded = true;
|
||||
|
||||
@Override
|
||||
public T mergeFramed(CodedInputStream input) throws IOException {
|
||||
int length = input.readRawVarint32();
|
||||
int oldLimit = input.pushLimit(length);
|
||||
T rc = mergeUnframed(input.readRawBytes(length));
|
||||
input.popLimit(oldLimit);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public T mergeUnframed(Buffer data) throws InvalidProtocolBufferException {
|
||||
encodedForm = data;
|
||||
decoded = false;
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Buffer toUnframedBuffer() {
|
||||
if (encodedForm == null) {
|
||||
encodedForm = super.toUnframedBuffer();
|
||||
}
|
||||
return encodedForm;
|
||||
}
|
||||
|
||||
protected void load() {
|
||||
if (!decoded) {
|
||||
decoded = true;
|
||||
try {
|
||||
Buffer originalForm = encodedForm;
|
||||
encodedForm=null;
|
||||
CodedInputStream input = new CodedInputStream(originalForm);
|
||||
mergeUnframed(input);
|
||||
input.checkLastTagWas(0);
|
||||
// We need to reset the encoded form because the mergeUnframed
|
||||
// from a stream clears it out.
|
||||
encodedForm = originalForm;
|
||||
checktInitialized();
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException("Deferred message decoding failed: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void loadAndClear() {
|
||||
super.loadAndClear();
|
||||
load();
|
||||
encodedForm = null;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
super.clear();
|
||||
encodedForm = null;
|
||||
decoded = true;
|
||||
}
|
||||
|
||||
public boolean isDecoded() {
|
||||
return decoded;
|
||||
}
|
||||
|
||||
public boolean isEncoded() {
|
||||
return encodedForm != null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc.
|
||||
// http://code.google.com/p/protobuf/
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package org.apache.activemq.protobuf;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Thrown when a protocol message being parsed is invalid in some way, e.g. it
|
||||
* contains a malformed varint or a negative byte length.
|
||||
*
|
||||
* @author kenton@google.com Kenton Varda
|
||||
*/
|
||||
public class InvalidProtocolBufferException extends IOException {
|
||||
private static final long serialVersionUID = 5685337441004132240L;
|
||||
|
||||
public InvalidProtocolBufferException(String description) {
|
||||
super(description);
|
||||
}
|
||||
|
||||
static InvalidProtocolBufferException truncatedMessage() {
|
||||
return new InvalidProtocolBufferException("While parsing a protocol message, the input ended unexpectedly " + "in the middle of a field. This could mean either than the " + "input has been truncated or that an embedded message "
|
||||
+ "misreported its own length.");
|
||||
}
|
||||
|
||||
static InvalidProtocolBufferException negativeSize() {
|
||||
return new InvalidProtocolBufferException("CodedInputStream encountered an embedded string or message " + "which claimed to have negative size.");
|
||||
}
|
||||
|
||||
static InvalidProtocolBufferException malformedVarint() {
|
||||
return new InvalidProtocolBufferException("CodedInputStream encountered a malformed varint.");
|
||||
}
|
||||
|
||||
static InvalidProtocolBufferException invalidTag() {
|
||||
return new InvalidProtocolBufferException("Protocol message contained an invalid tag (zero).");
|
||||
}
|
||||
|
||||
static InvalidProtocolBufferException invalidEndTag() {
|
||||
return new InvalidProtocolBufferException("Protocol message end-group tag did not match expected tag.");
|
||||
}
|
||||
|
||||
static InvalidProtocolBufferException invalidWireType() {
|
||||
return new InvalidProtocolBufferException("Protocol message tag had invalid wire type.");
|
||||
}
|
||||
|
||||
static InvalidProtocolBufferException recursionLimitExceeded() {
|
||||
return new InvalidProtocolBufferException("Protocol message had too many levels of nesting. May be malicious. " + "Use CodedInputStream.setRecursionLimit() to increase the depth limit.");
|
||||
}
|
||||
|
||||
static InvalidProtocolBufferException sizeLimitExceeded() {
|
||||
return new InvalidProtocolBufferException("Protocol message was too large. May be malicious. " + "Use CodedInputStream.setSizeLimit() to increase the size limit.");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.activemq.protobuf;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public interface Message<T> {
|
||||
|
||||
public T clone() throws CloneNotSupportedException;
|
||||
|
||||
public int serializedSizeUnframed();
|
||||
|
||||
public int serializedSizeFramed();
|
||||
|
||||
public void clear();
|
||||
|
||||
public T assertInitialized() throws UninitializedMessageException;
|
||||
|
||||
public T mergeFrom(T other);
|
||||
|
||||
|
||||
public T mergeUnframed(byte[] data) throws InvalidProtocolBufferException;
|
||||
|
||||
public T mergeFramed(byte[] data) throws InvalidProtocolBufferException;
|
||||
|
||||
public T mergeUnframed(Buffer buffer) throws InvalidProtocolBufferException;
|
||||
|
||||
public T mergeFramed(Buffer buffer) throws InvalidProtocolBufferException;
|
||||
|
||||
public T mergeUnframed(InputStream input) throws IOException;
|
||||
|
||||
public T mergeFramed(InputStream input) throws IOException;
|
||||
|
||||
public T mergeUnframed(CodedInputStream input) throws IOException;
|
||||
|
||||
public T mergeFramed(CodedInputStream input) throws IOException;
|
||||
|
||||
|
||||
public Buffer toUnframedBuffer();
|
||||
|
||||
public Buffer toFramedBuffer();
|
||||
|
||||
public byte[] toUnframedByteArray();
|
||||
|
||||
public byte[] toFramedByteArray();
|
||||
|
||||
public void writeUnframed(CodedOutputStream output) throws java.io.IOException;
|
||||
|
||||
public void writeFramed(CodedOutputStream output) throws java.io.IOException;
|
||||
|
||||
public void writeUnframed(OutputStream output) throws IOException;
|
||||
|
||||
public void writeFramed(OutputStream output) throws java.io.IOException;
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.activemq.protobuf;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public interface MessageBuffer<B, MB extends MessageBuffer> extends PBMessage<B, MB> {
|
||||
|
||||
public int serializedSizeUnframed();
|
||||
|
||||
public int serializedSizeFramed();
|
||||
|
||||
public Buffer toUnframedBuffer();
|
||||
|
||||
public Buffer toFramedBuffer();
|
||||
|
||||
public byte[] toUnframedByteArray();
|
||||
|
||||
public byte[] toFramedByteArray();
|
||||
|
||||
public void writeUnframed(CodedOutputStream output) throws java.io.IOException;
|
||||
|
||||
public void writeFramed(CodedOutputStream output) throws java.io.IOException;
|
||||
|
||||
public void writeUnframed(OutputStream output) throws IOException;
|
||||
|
||||
public void writeFramed(OutputStream output) throws java.io.IOException;
|
||||
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.activemq.protobuf;
|
||||
|
||||
import static org.apache.activemq.protobuf.WireFormat.WIRETYPE_LENGTH_DELIMITED;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Collection;
|
||||
|
||||
|
||||
final public class MessageBufferSupport {
|
||||
|
||||
public static final String FORZEN_ERROR_MESSAGE = "Modification not allowed after object has been fozen. Try modifying a copy of this object.";
|
||||
|
||||
static public Buffer toUnframedBuffer(MessageBuffer message) {
|
||||
try {
|
||||
int size = message.serializedSizeUnframed();
|
||||
BufferOutputStream baos = new BufferOutputStream(size);
|
||||
CodedOutputStream output = new CodedOutputStream(baos);
|
||||
message.writeUnframed(output);
|
||||
Buffer rc = baos.toBuffer();
|
||||
assert rc.length == size : "Did not write as much data as expected.";
|
||||
return rc;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Serializing to a byte array threw an IOException " + "(should never happen).", e);
|
||||
}
|
||||
}
|
||||
|
||||
static public Buffer toFramedBuffer(MessageBuffer message) {
|
||||
try {
|
||||
int size = message.serializedSizeFramed();
|
||||
BufferOutputStream baos = new BufferOutputStream(size);
|
||||
CodedOutputStream output = new CodedOutputStream(baos);
|
||||
message.writeFramed(output);
|
||||
Buffer rc = baos.toBuffer();
|
||||
assert rc.length==size : "Did not write as much data as expected.";
|
||||
return rc;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Serializing to a byte array threw an IOException " + "(should never happen).", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void writeMessage(CodedOutputStream output, int tag, MessageBuffer message) throws IOException {
|
||||
output.writeTag(tag, WIRETYPE_LENGTH_DELIMITED);
|
||||
message.writeFramed(output);
|
||||
}
|
||||
|
||||
public static int computeMessageSize(int tag, MessageBuffer message) {
|
||||
return CodedOutputStream.computeTagSize(tag) + message.serializedSizeFramed();
|
||||
}
|
||||
|
||||
public static Buffer readFrame(java.io.InputStream input) throws IOException {
|
||||
int length = readRawVarint32(input);
|
||||
byte[] data = new byte[length];
|
||||
int pos = 0;
|
||||
while (pos < length) {
|
||||
int r = input.read(data, pos, length - pos);
|
||||
if (r < 0) {
|
||||
throw new InvalidProtocolBufferException("Input stream ended before a full message frame could be read.");
|
||||
}
|
||||
pos += r;
|
||||
}
|
||||
return new Buffer(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a raw Varint from the stream. If larger than 32 bits, discard the
|
||||
* upper bits.
|
||||
*/
|
||||
static public int readRawVarint32(InputStream is) throws IOException {
|
||||
byte tmp = readRawByte(is);
|
||||
if (tmp >= 0) {
|
||||
return tmp;
|
||||
}
|
||||
int result = tmp & 0x7f;
|
||||
if ((tmp = readRawByte(is)) >= 0) {
|
||||
result |= tmp << 7;
|
||||
} else {
|
||||
result |= (tmp & 0x7f) << 7;
|
||||
if ((tmp = readRawByte(is)) >= 0) {
|
||||
result |= tmp << 14;
|
||||
} else {
|
||||
result |= (tmp & 0x7f) << 14;
|
||||
if ((tmp = readRawByte(is)) >= 0) {
|
||||
result |= tmp << 21;
|
||||
} else {
|
||||
result |= (tmp & 0x7f) << 21;
|
||||
result |= (tmp = readRawByte(is)) << 28;
|
||||
if (tmp < 0) {
|
||||
// Discard upper 32 bits.
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if (readRawByte(is) >= 0)
|
||||
return result;
|
||||
}
|
||||
throw new InvalidProtocolBufferException("CodedInputStream encountered a malformed varint.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static public byte readRawByte(InputStream is) throws IOException {
|
||||
int rc = is.read();
|
||||
if (rc == -1) {
|
||||
throw new InvalidProtocolBufferException("While parsing a protocol message, the input ended unexpectedly " + "in the middle of a field. This could mean either than the " + "input has been truncated or that an embedded message "
|
||||
+ "misreported its own length.");
|
||||
}
|
||||
return (byte) rc;
|
||||
}
|
||||
|
||||
static public <T> void addAll(Iterable<T> values, Collection<? super T> list) {
|
||||
if (values instanceof Collection) {
|
||||
@SuppressWarnings("unsafe")
|
||||
Collection<T> collection = (Collection<T>) values;
|
||||
list.addAll(collection);
|
||||
} else {
|
||||
for (T value : values) {
|
||||
list.add(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.activemq.protobuf;
|
||||
|
||||
public interface PBMessage <Bean, Buffer extends MessageBuffer>{
|
||||
public Bean copy();
|
||||
public boolean frozen();
|
||||
public Buffer freeze();
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.activemq.protobuf;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
final public class UTF8Buffer extends Buffer {
|
||||
|
||||
int hashCode;
|
||||
String value;
|
||||
|
||||
public UTF8Buffer(Buffer other) {
|
||||
super(other);
|
||||
}
|
||||
|
||||
public UTF8Buffer(byte[] data, int offset, int length) {
|
||||
super(data, offset, length);
|
||||
}
|
||||
|
||||
public UTF8Buffer(byte[] data) {
|
||||
super(data);
|
||||
}
|
||||
|
||||
public UTF8Buffer(String input) {
|
||||
super(encode(input));
|
||||
}
|
||||
|
||||
public UTF8Buffer compact() {
|
||||
if (length != data.length) {
|
||||
return new UTF8Buffer(toByteArray());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
if( value==null ) {
|
||||
value = decode(this);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Buffer other) {
|
||||
// Do a char comparison.. not a byte for byte comparison.
|
||||
return toString().compareTo(other.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if( obj==this )
|
||||
return true;
|
||||
|
||||
if( obj==null || obj.getClass()!=UTF8Buffer.class )
|
||||
return false;
|
||||
|
||||
return equals((Buffer)obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
if( hashCode==0 ) {
|
||||
hashCode = super.hashCode();;
|
||||
}
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
static public byte[] encode(String value)
|
||||
{
|
||||
try {
|
||||
return value.getBytes("UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException("A UnsupportedEncodingException was thrown for teh UTF-8 encoding. (This should never happen)");
|
||||
}
|
||||
}
|
||||
|
||||
static public String decode(Buffer buffer)
|
||||
{
|
||||
try {
|
||||
return new String(buffer.getData(), buffer.getOffset(), buffer.getLength(), "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException("A UnsupportedEncodingException was thrown for teh UTF-8 encoding. (This should never happen)");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc.
|
||||
// http://code.google.com/p/protobuf/
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package org.apache.activemq.protobuf;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Thrown when attempting to build a protocol message that is missing required
|
||||
* fields. This is a {@code RuntimeException} because it normally represents a
|
||||
* programming error: it happens when some code which constructs a message fails
|
||||
* to set all the fields. {@code parseFrom()} methods <b>do not</b> throw this;
|
||||
* they throw an {@link InvalidProtocolBufferException} if required fields are
|
||||
* missing, because it is not a programming error to receive an incomplete
|
||||
* message. In other words, {@code UninitializedMessageException} should never
|
||||
* be thrown by correct code, but {@code InvalidProtocolBufferException} might
|
||||
* be.
|
||||
*
|
||||
* @author kenton@google.com Kenton Varda
|
||||
*/
|
||||
public class UninitializedMessageException extends RuntimeException {
|
||||
|
||||
public UninitializedMessageException(List<String> missingFields) {
|
||||
super(buildDescription(missingFields));
|
||||
this.missingFields = missingFields;
|
||||
}
|
||||
|
||||
private final List<String> missingFields;
|
||||
|
||||
/**
|
||||
* Get a list of human-readable names of required fields missing from this
|
||||
* message. Each name is a full path to a field, e.g. "foo.bar[5].baz".
|
||||
*/
|
||||
public List<String> getMissingFields() {
|
||||
return Collections.unmodifiableList(missingFields);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts this exception to an {@link InvalidProtocolBufferException}.
|
||||
* When a parsed message is missing required fields, this should be thrown
|
||||
* instead of {@code UninitializedMessageException}.
|
||||
*/
|
||||
public InvalidProtocolBufferException asInvalidProtocolBufferException() {
|
||||
return new InvalidProtocolBufferException(getMessage());
|
||||
}
|
||||
|
||||
/** Construct the description string for this exception. */
|
||||
private static String buildDescription(List<String> missingFields) {
|
||||
StringBuilder description = new StringBuilder("Message missing required fields: ");
|
||||
boolean first = true;
|
||||
for (String field : missingFields) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
description.append(", ");
|
||||
}
|
||||
description.append(field);
|
||||
}
|
||||
return description.toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc.
|
||||
// http://code.google.com/p/protobuf/
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package org.apache.activemq.protobuf;
|
||||
|
||||
/**
|
||||
* This class is used internally by the Protocol Buffer library and generated
|
||||
* message implementations. It is public only because those generated messages
|
||||
* do not reside in the {@code protocol2} package. Others should not use this
|
||||
* class directly.
|
||||
*
|
||||
* This class contains constants and helper functions useful for dealing with
|
||||
* the Protocol Buffer wire format.
|
||||
*
|
||||
* @author kenton@google.com Kenton Varda
|
||||
*/
|
||||
public final class WireFormat {
|
||||
// Do not allow instantiation.
|
||||
private WireFormat() {
|
||||
}
|
||||
|
||||
public static final int WIRETYPE_VARINT = 0;
|
||||
public static final int WIRETYPE_FIXED64 = 1;
|
||||
public static final int WIRETYPE_LENGTH_DELIMITED = 2;
|
||||
public static final int WIRETYPE_START_GROUP = 3;
|
||||
public static final int WIRETYPE_END_GROUP = 4;
|
||||
public static final int WIRETYPE_FIXED32 = 5;
|
||||
|
||||
public static final int TAG_TYPE_BITS = 3;
|
||||
public static final int TAG_TYPE_MASK = (1 << TAG_TYPE_BITS) - 1;
|
||||
|
||||
/** Given a tag value, determines the wire type (the lower 3 bits). */
|
||||
public static int getTagWireType(int tag) {
|
||||
return tag & TAG_TYPE_MASK;
|
||||
}
|
||||
|
||||
/** Given a tag value, determines the field number (the upper 29 bits). */
|
||||
public static int getTagFieldNumber(int tag) {
|
||||
return tag >>> TAG_TYPE_BITS;
|
||||
}
|
||||
|
||||
/** Makes a tag value given a field number and wire type. */
|
||||
public static int makeTag(int fieldNumber, int wireType) {
|
||||
return (fieldNumber << TAG_TYPE_BITS) | wireType;
|
||||
}
|
||||
|
||||
// Field numbers for feilds in MessageSet wire format.
|
||||
public static final int MESSAGE_SET_ITEM = 1;
|
||||
public static final int MESSAGE_SET_TYPE_ID = 2;
|
||||
public static final int MESSAGE_SET_MESSAGE = 3;
|
||||
|
||||
// Tag numbers.
|
||||
public static final int MESSAGE_SET_ITEM_TAG = makeTag(MESSAGE_SET_ITEM, WIRETYPE_START_GROUP);
|
||||
public static final int MESSAGE_SET_ITEM_END_TAG = makeTag(MESSAGE_SET_ITEM, WIRETYPE_END_GROUP);
|
||||
public static final int MESSAGE_SET_TYPE_ID_TAG = makeTag(MESSAGE_SET_TYPE_ID, WIRETYPE_VARINT);
|
||||
public static final int MESSAGE_SET_MESSAGE_TAG = makeTag(MESSAGE_SET_MESSAGE, WIRETYPE_LENGTH_DELIMITED);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,115 @@
|
|||
/**
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.activemq.protobuf.compiler;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Support utility that can be used to set the properties on any object
|
||||
* using command line arguments.
|
||||
*
|
||||
* @author <a href="http://hiramchirino.com">Hiram Chirino</a>
|
||||
*/
|
||||
public class CommandLineSupport {
|
||||
|
||||
/**
|
||||
* Sets the properties of an object given the command line args.
|
||||
*
|
||||
* if args contains: --ack-mode=AUTO --url=tcp://localhost:61616 --persistent
|
||||
*
|
||||
* then it will try to call the following setters on the target object.
|
||||
*
|
||||
* target.setAckMode("AUTO");
|
||||
* target.setURL(new URI("tcp://localhost:61616") );
|
||||
* target.setPersistent(true);
|
||||
*
|
||||
* Notice the the proper conversion for the argument is determined by examining the
|
||||
* setter argument type.
|
||||
*
|
||||
* @param target the object that will have it's properties set
|
||||
* @param args the command line options
|
||||
* @return any arguments that are not valid options for the target
|
||||
*/
|
||||
static public String[] setOptions(Object target, String []args) {
|
||||
ArrayList rc = new ArrayList();
|
||||
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if( args[i] == null )
|
||||
continue;
|
||||
|
||||
if( args[i].startsWith("--") ) {
|
||||
|
||||
// --options without a specified value are considered boolean flags that are enabled.
|
||||
String value="true";
|
||||
String name = args[i].substring(2);
|
||||
|
||||
// if --option=value case
|
||||
int p = name.indexOf("=");
|
||||
if( p > 0 ) {
|
||||
value = name.substring(p+1);
|
||||
name = name.substring(0,p);
|
||||
}
|
||||
|
||||
// name not set, then it's an unrecognized option
|
||||
if( name.length()==0 ) {
|
||||
rc.add(args[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
String propName = convertOptionToPropertyName(name);
|
||||
if( !IntrospectionSupport.setProperty(target, propName, value) ) {
|
||||
rc.add(args[i]);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
rc.add(args[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
String r[] = new String[rc.size()];
|
||||
rc.toArray(r);
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* converts strings like: test-enabled to testEnabled
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
private static String convertOptionToPropertyName(String name) {
|
||||
String rc="";
|
||||
|
||||
// Look for '-' and strip and then convert the subsequent char to uppercase
|
||||
int p = name.indexOf("-");
|
||||
while( p > 0 ) {
|
||||
// strip
|
||||
rc += name.substring(0, p);
|
||||
name = name.substring(p+1);
|
||||
|
||||
// can I convert the next char to upper?
|
||||
if( name.length() >0 ) {
|
||||
rc += name.substring(0,1).toUpperCase();
|
||||
name = name.substring(1);
|
||||
}
|
||||
|
||||
p = name.indexOf("-");
|
||||
}
|
||||
return rc+name;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.activemq.protobuf.compiler;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class CompilerException extends Exception {
|
||||
private final List<String> errors;
|
||||
|
||||
public CompilerException(List<String> errors) {
|
||||
this.errors = errors;
|
||||
}
|
||||
|
||||
public List<String> getErrors() {
|
||||
return errors;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,136 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.activemq.protobuf.compiler;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class EnumDescriptor implements TypeDescriptor {
|
||||
|
||||
private String name;
|
||||
private Map<String,EnumFieldDescriptor> fields= new LinkedHashMap<String, EnumFieldDescriptor>();
|
||||
private final ProtoDescriptor protoDescriptor;
|
||||
private final MessageDescriptor parent;
|
||||
private Map<String, OptionDescriptor> options = new LinkedHashMap<String, OptionDescriptor>();
|
||||
|
||||
public EnumDescriptor(ProtoDescriptor protoDescriptor, MessageDescriptor parent) {
|
||||
this.protoDescriptor = protoDescriptor;
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public Map<String,EnumFieldDescriptor> getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setFields(Map<String,EnumFieldDescriptor> fields) {
|
||||
this.fields = fields;
|
||||
}
|
||||
public ProtoDescriptor getProtoDescriptor() {
|
||||
return protoDescriptor;
|
||||
}
|
||||
|
||||
private String getOption(Map<String, OptionDescriptor> options, String optionName, String defaultValue) {
|
||||
OptionDescriptor optionDescriptor = options.get(optionName);
|
||||
if (optionDescriptor == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
return optionDescriptor.getValue();
|
||||
}
|
||||
|
||||
private String constantToUCamelCase(String name) {
|
||||
boolean upNext=true;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < name.length(); i++) {
|
||||
char c = name.charAt(i);
|
||||
if( Character.isJavaIdentifierPart(c) && Character.isLetterOrDigit(c)) {
|
||||
if( upNext ) {
|
||||
c = Character.toUpperCase(c);
|
||||
upNext=false;
|
||||
} else {
|
||||
c = Character.toLowerCase(c);
|
||||
}
|
||||
sb.append(c);
|
||||
} else {
|
||||
upNext=true;
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public void validate(List<String> errors) {
|
||||
String createMessage = getOption(getOptions(), "java_create_message", null);
|
||||
if( "true".equals(createMessage) ) {
|
||||
for (EnumFieldDescriptor field : getFields().values()) {
|
||||
String type = constantToUCamelCase(field.getName());
|
||||
|
||||
TypeDescriptor typeDescriptor=null;
|
||||
// Find the type def for that guy..
|
||||
if( parent!=null ) {
|
||||
typeDescriptor = parent.getType(type);
|
||||
}
|
||||
if( typeDescriptor == null ) {
|
||||
typeDescriptor = protoDescriptor.getType(type);
|
||||
}
|
||||
if( typeDescriptor == null ) {
|
||||
errors.add("ENUM constant '"+field.getName()+"' did not find expected associated message: "+type);
|
||||
} else {
|
||||
field.associate(typeDescriptor);
|
||||
typeDescriptor.associate(field);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public MessageDescriptor getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public String getQName() {
|
||||
if( parent==null ) {
|
||||
return name;
|
||||
} else {
|
||||
return parent.getQName()+"."+name;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isEnum() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public Map<String, OptionDescriptor> getOptions() {
|
||||
return options;
|
||||
}
|
||||
|
||||
public void setOptions(Map<String, OptionDescriptor> options) {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
public void associate(EnumFieldDescriptor desc) {
|
||||
throw new RuntimeException("not supported.");
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.activemq.protobuf.compiler;
|
||||
|
||||
public class EnumFieldDescriptor {
|
||||
|
||||
private String name;
|
||||
private int value;
|
||||
private final EnumDescriptor parent;
|
||||
private TypeDescriptor associatedType;
|
||||
|
||||
public EnumFieldDescriptor(EnumDescriptor parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setValue(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public EnumDescriptor getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public TypeDescriptor getAssociatedType() {
|
||||
return associatedType;
|
||||
}
|
||||
|
||||
public void associate(TypeDescriptor associatedType) {
|
||||
this.associatedType = associatedType;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.activemq.protobuf.compiler;
|
||||
|
||||
public class ExtensionsDescriptor {
|
||||
|
||||
private int first;
|
||||
private int last;
|
||||
private final MessageDescriptor parent;
|
||||
|
||||
public ExtensionsDescriptor(MessageDescriptor parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public void setFirst(int first) {
|
||||
this.first = first;
|
||||
}
|
||||
|
||||
public void setLast(int last) {
|
||||
this.last = last;
|
||||
}
|
||||
|
||||
public int getFirst() {
|
||||
return first;
|
||||
}
|
||||
|
||||
public int getLast() {
|
||||
return last;
|
||||
}
|
||||
|
||||
public MessageDescriptor getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,207 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.activemq.protobuf.compiler;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class FieldDescriptor {
|
||||
|
||||
public static final String STRING_TYPE = "string".intern();
|
||||
public static final String BOOL_TYPE = "bool".intern();
|
||||
public static final String BYTES_TYPE = "bytes".intern();
|
||||
public static final String DOUBLE_TYPE = "double".intern();
|
||||
public static final String FLOAT_TYPE = "float".intern();
|
||||
|
||||
public static final String INT32_TYPE = "int32".intern();
|
||||
public static final String INT64_TYPE = "int64".intern();
|
||||
public static final String UINT32_TYPE = "uint32".intern();
|
||||
public static final String UINT64_TYPE = "uint64".intern();
|
||||
public static final String SINT32_TYPE = "sint32".intern();
|
||||
public static final String SINT64_TYPE = "sint64".intern();
|
||||
public static final String FIXED32_TYPE = "fixed32".intern();
|
||||
public static final String FIXED64_TYPE = "fixed64".intern();
|
||||
public static final String SFIXED32_TYPE = "sfixed32".intern();
|
||||
public static final String SFIXED64_TYPE = "sfixed64".intern();
|
||||
|
||||
public static final String REQUIRED_RULE = "required".intern();
|
||||
public static final String OPTIONAL_RULE= "optional".intern();
|
||||
public static final String REPEATED_RULE = "repeated".intern();
|
||||
|
||||
public static final Set<String> INT32_TYPES = new HashSet<String>();
|
||||
public static final Set<String> INT64_TYPES = new HashSet<String>();
|
||||
public static final Set<String> INTEGER_TYPES = new HashSet<String>();
|
||||
public static final Set<String> NUMBER_TYPES = new HashSet<String>();
|
||||
public static final Set<String> SCALAR_TYPES = new HashSet<String>();
|
||||
|
||||
public static final Set<String> SIGNED_TYPES = new HashSet<String>();
|
||||
public static final Set<String> UNSIGNED_TYPES = new HashSet<String>();
|
||||
|
||||
static {
|
||||
INT32_TYPES.add(INT32_TYPE);
|
||||
INT32_TYPES.add(UINT32_TYPE);
|
||||
INT32_TYPES.add(SINT32_TYPE);
|
||||
INT32_TYPES.add(FIXED32_TYPE);
|
||||
INT32_TYPES.add(SFIXED32_TYPE);
|
||||
|
||||
INT64_TYPES.add(INT64_TYPE);
|
||||
INT64_TYPES.add(UINT64_TYPE);
|
||||
INT64_TYPES.add(SINT64_TYPE);
|
||||
INT64_TYPES.add(FIXED64_TYPE);
|
||||
INT64_TYPES.add(SFIXED64_TYPE);
|
||||
|
||||
INTEGER_TYPES.addAll(INT32_TYPES);
|
||||
INTEGER_TYPES.addAll(INT64_TYPES);
|
||||
|
||||
NUMBER_TYPES.addAll(INTEGER_TYPES);
|
||||
NUMBER_TYPES.add(DOUBLE_TYPE);
|
||||
NUMBER_TYPES.add(FLOAT_TYPE);
|
||||
|
||||
SCALAR_TYPES.addAll(NUMBER_TYPES);
|
||||
SCALAR_TYPES.add(STRING_TYPE);
|
||||
SCALAR_TYPES.add(BOOL_TYPE);
|
||||
SCALAR_TYPES.add(BYTES_TYPE);
|
||||
}
|
||||
|
||||
|
||||
private String name;
|
||||
private String type;
|
||||
private String rule;
|
||||
private int tag;
|
||||
private Map<String,OptionDescriptor> options;
|
||||
private TypeDescriptor typeDescriptor;
|
||||
private final MessageDescriptor parent;
|
||||
private MessageDescriptor group;
|
||||
|
||||
public FieldDescriptor(MessageDescriptor parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public void validate(List<String> errors) {
|
||||
if( group!=null ) {
|
||||
typeDescriptor=group;
|
||||
}
|
||||
if( !SCALAR_TYPES.contains(type) ) {
|
||||
// Find the type def for that guy..
|
||||
if( typeDescriptor==null ) {
|
||||
typeDescriptor = parent.getType(type);
|
||||
}
|
||||
if( typeDescriptor == null ) {
|
||||
typeDescriptor = parent.getProtoDescriptor().getType(type);
|
||||
}
|
||||
if( typeDescriptor == null ) {
|
||||
errors.add("Field type not found: "+type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isGroup() {
|
||||
return group!=null;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getRule() {
|
||||
return rule;
|
||||
}
|
||||
public void setRule(String rule) {
|
||||
this.rule = rule.intern();
|
||||
}
|
||||
|
||||
public boolean isOptional() {
|
||||
return this.rule == OPTIONAL_RULE;
|
||||
}
|
||||
public boolean isRequired() {
|
||||
return this.rule == REQUIRED_RULE;
|
||||
}
|
||||
public boolean isRepeated() {
|
||||
return this.rule == REPEATED_RULE;
|
||||
}
|
||||
|
||||
public int getTag() {
|
||||
return tag;
|
||||
}
|
||||
public void setTag(int tag) {
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
public Map<String,OptionDescriptor> getOptions() {
|
||||
return options;
|
||||
}
|
||||
public void setOptions(Map<String,OptionDescriptor> options) {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
public void setType(String type) {
|
||||
this.type = type.intern();
|
||||
}
|
||||
|
||||
public boolean isMessageType() {
|
||||
return !SCALAR_TYPES.contains(type);
|
||||
}
|
||||
|
||||
public boolean isScalarType() {
|
||||
return SCALAR_TYPES.contains(type);
|
||||
}
|
||||
|
||||
public boolean isNumberType() {
|
||||
return NUMBER_TYPES.contains(type);
|
||||
}
|
||||
|
||||
public boolean isIntegerType() {
|
||||
return INTEGER_TYPES.contains(type);
|
||||
}
|
||||
|
||||
public boolean isInteger32Type() {
|
||||
return INT32_TYPES.contains(type);
|
||||
}
|
||||
|
||||
public boolean isInteger64Type() {
|
||||
return INT64_TYPES.contains(type);
|
||||
}
|
||||
|
||||
public boolean isStringType() {
|
||||
return type==STRING_TYPE;
|
||||
}
|
||||
|
||||
public TypeDescriptor getTypeDescriptor() {
|
||||
return typeDescriptor;
|
||||
}
|
||||
|
||||
public void setTypeDescriptor(TypeDescriptor typeDescriptor) {
|
||||
this.typeDescriptor = typeDescriptor;
|
||||
}
|
||||
|
||||
public MessageDescriptor getGroup() {
|
||||
return group;
|
||||
}
|
||||
public void setGroup(MessageDescriptor group) {
|
||||
this.group = group;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,324 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.activemq.protobuf.compiler;
|
||||
|
||||
import java.beans.PropertyEditor;
|
||||
import java.beans.PropertyEditorManager;
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
/**
|
||||
* Support class used to do introspection/reflection based setting and getting of properties on a Java Bean.
|
||||
*
|
||||
* @author <a href="http://hiramchirino.com">Hiram Chirino</a>
|
||||
*/
|
||||
public final class IntrospectionSupport {
|
||||
|
||||
private IntrospectionSupport() {
|
||||
}
|
||||
|
||||
public static boolean getProperties(Object target, Map props, String optionPrefix) {
|
||||
|
||||
boolean rc = false;
|
||||
if (target == null) {
|
||||
throw new IllegalArgumentException("target was null.");
|
||||
}
|
||||
if (props == null) {
|
||||
throw new IllegalArgumentException("props was null.");
|
||||
}
|
||||
|
||||
if (optionPrefix == null) {
|
||||
optionPrefix = "";
|
||||
}
|
||||
|
||||
Class clazz = target.getClass();
|
||||
Method[] methods = clazz.getMethods();
|
||||
for (int i = 0; i < methods.length; i++) {
|
||||
Method method = methods[i];
|
||||
String name = method.getName();
|
||||
Class type = method.getReturnType();
|
||||
Class params[] = method.getParameterTypes();
|
||||
if (name.startsWith("get") && params.length == 0 && type != null && isSettableType(type)) {
|
||||
|
||||
try {
|
||||
|
||||
Object value = method.invoke(target, new Object[] {});
|
||||
if (value == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String strValue = convertToString(value, type);
|
||||
if (strValue == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
name = name.substring(3, 4).toLowerCase() + name.substring(4);
|
||||
props.put(optionPrefix + name, strValue);
|
||||
rc = true;
|
||||
|
||||
} catch (Throwable ignore) {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
public static boolean setProperties(Object target, Map<String, ?> props, String optionPrefix) {
|
||||
boolean rc = false;
|
||||
if (target == null) {
|
||||
throw new IllegalArgumentException("target was null.");
|
||||
}
|
||||
if (props == null) {
|
||||
throw new IllegalArgumentException("props was null.");
|
||||
}
|
||||
|
||||
for (Iterator<String> iter = props.keySet().iterator(); iter.hasNext();) {
|
||||
String name = iter.next();
|
||||
if (name.startsWith(optionPrefix)) {
|
||||
Object value = props.get(name);
|
||||
name = name.substring(optionPrefix.length());
|
||||
if (setProperty(target, name, value)) {
|
||||
iter.remove();
|
||||
rc = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
public static Map<String, Object> extractProperties(Map props, String optionPrefix) {
|
||||
if (props == null) {
|
||||
throw new IllegalArgumentException("props was null.");
|
||||
}
|
||||
|
||||
HashMap<String, Object> rc = new HashMap<String, Object>(props.size());
|
||||
|
||||
for (Iterator iter = props.keySet().iterator(); iter.hasNext();) {
|
||||
String name = (String)iter.next();
|
||||
if (name.startsWith(optionPrefix)) {
|
||||
Object value = props.get(name);
|
||||
name = name.substring(optionPrefix.length());
|
||||
rc.put(name, value);
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
public static boolean setProperties(Object target, Map props) {
|
||||
boolean rc = false;
|
||||
|
||||
if (target == null) {
|
||||
throw new IllegalArgumentException("target was null.");
|
||||
}
|
||||
if (props == null) {
|
||||
throw new IllegalArgumentException("props was null.");
|
||||
}
|
||||
|
||||
for (Iterator iter = props.entrySet().iterator(); iter.hasNext();) {
|
||||
Map.Entry entry = (Entry)iter.next();
|
||||
if (setProperty(target, (String)entry.getKey(), entry.getValue())) {
|
||||
iter.remove();
|
||||
rc = true;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
public static boolean setProperty(Object target, String name, Object value) {
|
||||
try {
|
||||
Class clazz = target.getClass();
|
||||
Method setter = findSetterMethod(clazz, name);
|
||||
if (setter == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the type is null or it matches the needed type, just use the
|
||||
// value directly
|
||||
if (value == null || value.getClass() == setter.getParameterTypes()[0]) {
|
||||
setter.invoke(target, new Object[] {value});
|
||||
} else {
|
||||
// We need to convert it
|
||||
setter.invoke(target, new Object[] {convert(value, setter.getParameterTypes()[0])});
|
||||
}
|
||||
return true;
|
||||
} catch (Throwable ignore) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static Object convert(Object value, Class type) throws URISyntaxException {
|
||||
PropertyEditor editor = PropertyEditorManager.findEditor(type);
|
||||
if (editor != null) {
|
||||
editor.setAsText(value.toString());
|
||||
return editor.getValue();
|
||||
}
|
||||
if (type == URI.class) {
|
||||
return new URI(value.toString());
|
||||
}
|
||||
if (type == File.class) {
|
||||
return new File(value.toString());
|
||||
}
|
||||
if (type == File[].class) {
|
||||
ArrayList<File> files = new ArrayList<File>();
|
||||
StringTokenizer st = new StringTokenizer(value.toString(), ":");
|
||||
while(st.hasMoreTokens()) {
|
||||
String t = st.nextToken();
|
||||
if( t!=null && t.trim().length()>0 ) {
|
||||
files.add(new File(t.trim()));
|
||||
}
|
||||
}
|
||||
File rc[] = new File[files.size()];
|
||||
files.toArray(rc);
|
||||
return rc;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String convertToString(Object value, Class type) throws URISyntaxException {
|
||||
PropertyEditor editor = PropertyEditorManager.findEditor(type);
|
||||
if (editor != null) {
|
||||
editor.setValue(value);
|
||||
return editor.getAsText();
|
||||
}
|
||||
if (type == URI.class) {
|
||||
return ((URI)value).toString();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Method findSetterMethod(Class clazz, String name) {
|
||||
// Build the method name.
|
||||
name = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);
|
||||
Method[] methods = clazz.getMethods();
|
||||
for (int i = 0; i < methods.length; i++) {
|
||||
Method method = methods[i];
|
||||
Class params[] = method.getParameterTypes();
|
||||
if (method.getName().equals(name) && params.length == 1 && isSettableType(params[0])) {
|
||||
return method;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean isSettableType(Class clazz) {
|
||||
if (PropertyEditorManager.findEditor(clazz) != null) {
|
||||
return true;
|
||||
}
|
||||
if (clazz == URI.class) {
|
||||
return true;
|
||||
}
|
||||
if (clazz == File.class) {
|
||||
return true;
|
||||
}
|
||||
if (clazz == File[].class) {
|
||||
return true;
|
||||
}
|
||||
if (clazz == Boolean.class) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static String toString(Object target) {
|
||||
return toString(target, Object.class);
|
||||
}
|
||||
|
||||
public static String toString(Object target, Class stopClass) {
|
||||
LinkedHashMap<String, Object> map = new LinkedHashMap<String, Object>();
|
||||
addFields(target, target.getClass(), stopClass, map);
|
||||
StringBuffer buffer = new StringBuffer(simpleName(target.getClass()));
|
||||
buffer.append(" {");
|
||||
Set entrySet = map.entrySet();
|
||||
boolean first = true;
|
||||
for (Iterator iter = entrySet.iterator(); iter.hasNext();) {
|
||||
Map.Entry entry = (Map.Entry)iter.next();
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
buffer.append(", ");
|
||||
}
|
||||
buffer.append(entry.getKey());
|
||||
buffer.append(" = ");
|
||||
appendToString(buffer, entry.getValue());
|
||||
}
|
||||
buffer.append("}");
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
protected static void appendToString(StringBuffer buffer, Object value) {
|
||||
buffer.append(value);
|
||||
}
|
||||
|
||||
public static String simpleName(Class clazz) {
|
||||
String name = clazz.getName();
|
||||
int p = name.lastIndexOf(".");
|
||||
if (p >= 0) {
|
||||
name = name.substring(p + 1);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
private static void addFields(Object target, Class startClass, Class<Object> stopClass, LinkedHashMap<String, Object> map) {
|
||||
|
||||
if (startClass != stopClass) {
|
||||
addFields(target, startClass.getSuperclass(), stopClass, map);
|
||||
}
|
||||
|
||||
Field[] fields = startClass.getDeclaredFields();
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
Field field = fields[i];
|
||||
if (Modifier.isStatic(field.getModifiers()) || Modifier.isTransient(field.getModifiers())
|
||||
|| Modifier.isPrivate(field.getModifiers())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
field.setAccessible(true);
|
||||
Object o = field.get(target);
|
||||
if (o != null && o.getClass().isArray()) {
|
||||
try {
|
||||
o = Arrays.asList((Object[])o);
|
||||
} catch (Throwable e) {
|
||||
}
|
||||
}
|
||||
map.put(field.getName(), o);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,194 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.activemq.protobuf.compiler;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public class MessageDescriptor implements TypeDescriptor {
|
||||
|
||||
private String name;
|
||||
private ExtensionsDescriptor extensions;
|
||||
private Map<String,FieldDescriptor> fields = new LinkedHashMap<String, FieldDescriptor>();
|
||||
private Map<String,MessageDescriptor> messages = new LinkedHashMap<String,MessageDescriptor>();
|
||||
private Map<String,EnumDescriptor> enums = new LinkedHashMap<String, EnumDescriptor>();
|
||||
private final ProtoDescriptor protoDescriptor;
|
||||
private List<MessageDescriptor> extendsList = new ArrayList<MessageDescriptor>();
|
||||
private Map<String, OptionDescriptor> options = new LinkedHashMap<String, OptionDescriptor>();
|
||||
private List<EnumFieldDescriptor> associatedEnumFieldDescriptors = new ArrayList<EnumFieldDescriptor>();
|
||||
|
||||
private final MessageDescriptor parent;
|
||||
private MessageDescriptor baseType;
|
||||
|
||||
public MessageDescriptor(ProtoDescriptor protoDescriptor, MessageDescriptor parent) {
|
||||
this.protoDescriptor = protoDescriptor;
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public void validate(List<String> errors) {
|
||||
String baseName = getOption(getOptions(), "base_type", null);
|
||||
if( baseName!=null ) {
|
||||
if( baseType==null ) {
|
||||
baseType = (MessageDescriptor) getType(baseName);
|
||||
}
|
||||
if( baseType == null ) {
|
||||
baseType = (MessageDescriptor) getProtoDescriptor().getType(baseName);
|
||||
}
|
||||
if( baseType == null ) {
|
||||
errors.add("base_type option not valid, type not found: "+baseName);
|
||||
}
|
||||
|
||||
// Assert that all the fields in the base type are defined in this message defintion too.
|
||||
HashSet<String> baseFieldNames = new HashSet<String>(baseType.getFields().keySet());
|
||||
baseFieldNames.removeAll(getFields().keySet());
|
||||
|
||||
// Some fields were not defined in the sub class..
|
||||
if( !baseFieldNames.isEmpty() ) {
|
||||
for (String fieldName : baseFieldNames) {
|
||||
errors.add("base_type "+baseName+" field "+fieldName+" not defined in "+getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (FieldDescriptor field : fields.values()) {
|
||||
field.validate(errors);
|
||||
}
|
||||
for (EnumDescriptor o : enums.values()) {
|
||||
o.validate(errors);
|
||||
}
|
||||
for (MessageDescriptor o : messages.values()) {
|
||||
o.validate(errors);
|
||||
}
|
||||
}
|
||||
|
||||
public String getOption(Map<String, OptionDescriptor> options, String optionName, String defaultValue) {
|
||||
OptionDescriptor optionDescriptor = options.get(optionName);
|
||||
if (optionDescriptor == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
return optionDescriptor.getValue();
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setExtensions(ExtensionsDescriptor extensions) {
|
||||
this.extensions = extensions;
|
||||
}
|
||||
|
||||
public void setExtends(List<MessageDescriptor> extendsList) {
|
||||
this.extendsList = extendsList;
|
||||
}
|
||||
public List<MessageDescriptor> getExtends() {
|
||||
return extendsList;
|
||||
}
|
||||
|
||||
public void setFields(Map<String,FieldDescriptor> fields) {
|
||||
this.fields = fields;
|
||||
}
|
||||
|
||||
public void setMessages(Map<String,MessageDescriptor> messages) {
|
||||
this.messages = messages;
|
||||
}
|
||||
|
||||
public void setEnums(Map<String,EnumDescriptor> enums) {
|
||||
this.enums = enums;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getQName() {
|
||||
if( parent==null ) {
|
||||
return name;
|
||||
} else {
|
||||
return parent.getQName()+"."+name;
|
||||
}
|
||||
}
|
||||
|
||||
public ExtensionsDescriptor getExtensions() {
|
||||
return extensions;
|
||||
}
|
||||
|
||||
public Map<String,FieldDescriptor> getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public Map<String,MessageDescriptor> getMessages() {
|
||||
return messages;
|
||||
}
|
||||
|
||||
public Map<String,EnumDescriptor> getEnums() {
|
||||
return enums;
|
||||
}
|
||||
|
||||
public ProtoDescriptor getProtoDescriptor() {
|
||||
return protoDescriptor;
|
||||
}
|
||||
|
||||
public Map<String, OptionDescriptor> getOptions() {
|
||||
return options;
|
||||
}
|
||||
|
||||
public void setOptions(Map<String, OptionDescriptor> options) {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
public MessageDescriptor getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public TypeDescriptor getType(String t) {
|
||||
for (MessageDescriptor o : messages.values()) {
|
||||
if( t.equals(o.getName()) ) {
|
||||
return o;
|
||||
}
|
||||
if( t.startsWith(o.getName()+".") ) {
|
||||
return o.getType( t.substring(o.getName().length()+1) );
|
||||
}
|
||||
}
|
||||
for (EnumDescriptor o : enums.values()) {
|
||||
if( t.equals(o.getName()) ) {
|
||||
return o;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isEnum() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public MessageDescriptor getBaseType() {
|
||||
return baseType;
|
||||
}
|
||||
|
||||
public void associate(EnumFieldDescriptor desc) {
|
||||
associatedEnumFieldDescriptors.add(desc);
|
||||
}
|
||||
|
||||
public List<EnumFieldDescriptor> getAssociatedEnumFieldDescriptors() {
|
||||
return associatedEnumFieldDescriptors;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.activemq.protobuf.compiler;
|
||||
|
||||
public class MethodDescriptor {
|
||||
|
||||
private final ProtoDescriptor protoDescriptor;
|
||||
private String name;
|
||||
private String parameter;
|
||||
private String returns;
|
||||
|
||||
public MethodDescriptor(ProtoDescriptor protoDescriptor) {
|
||||
this.protoDescriptor = protoDescriptor;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setParameter(String parameter) {
|
||||
this.parameter = parameter;
|
||||
}
|
||||
|
||||
public void setReturns(String returns) {
|
||||
this.returns = returns;
|
||||
}
|
||||
|
||||
public ProtoDescriptor getProtoDescriptor() {
|
||||
return protoDescriptor;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getParameter() {
|
||||
return parameter;
|
||||
}
|
||||
|
||||
public String getReturns() {
|
||||
return returns;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.activemq.protobuf.compiler;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class OptionDescriptor {
|
||||
|
||||
private String name;
|
||||
private String value;
|
||||
|
||||
public OptionDescriptor() {
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public void validate(List<String> errors) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.activemq.protobuf.compiler;
|
||||
|
||||
import org.apache.activemq.protobuf.compiler.TextFormat.InvalidEscapeSequence;
|
||||
import org.apache.activemq.protobuf.compiler.parser.ParseException;
|
||||
import org.apache.activemq.protobuf.compiler.parser.Token;
|
||||
|
||||
public class ParserSupport {
|
||||
|
||||
public static String decodeString(Token token) throws ParseException {
|
||||
|
||||
// StringBuilder sb = new StringBuilder();
|
||||
// for (int i = 1; i < value.length() - 1; i++) {
|
||||
// char c = value.charAt(i);
|
||||
// if (c == '\'') {
|
||||
// if( i+1 < (value.length() - 1) ) {
|
||||
// char e = value.charAt(i+1);
|
||||
// switch(e) {
|
||||
// case 'a':
|
||||
// sb.append((char)0x07);
|
||||
// break;
|
||||
// case 'b':
|
||||
// sb.append("\b");
|
||||
// break;
|
||||
// case 'f':
|
||||
// sb.append("\f");
|
||||
// break;
|
||||
// case 'n':
|
||||
// sb.append("\n");
|
||||
// break;
|
||||
// case 'r':
|
||||
// sb.append("\r");
|
||||
// break;
|
||||
// case 't':
|
||||
// sb.append("\t");
|
||||
// break;
|
||||
// case 'v':
|
||||
// sb.append((char)0x0b);
|
||||
// break;
|
||||
// case '\\':
|
||||
// sb.append("\\");
|
||||
// break;
|
||||
// case '\'':
|
||||
// sb.append("'");
|
||||
// break;
|
||||
// case '\"':
|
||||
// sb.append("\"");
|
||||
// break;
|
||||
// default:
|
||||
// sb.append(e);
|
||||
// break;
|
||||
// }
|
||||
// } else {
|
||||
// throw new RuntimeException("Invalid string litteral: "+value);
|
||||
// }
|
||||
// }
|
||||
// sb.append(c);
|
||||
// }
|
||||
// return sb.toString();
|
||||
|
||||
try {
|
||||
return TextFormat.unescapeText(token.image.substring(1, token.image.length()-1));
|
||||
} catch (InvalidEscapeSequence e) {
|
||||
throw new ParseException("Invalid string litteral at line " + token.next.beginLine + ", column " + token.next.beginColumn+": "+e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,164 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.activemq.protobuf.compiler;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ProtoDescriptor {
|
||||
|
||||
private String packageName;
|
||||
private Map<String, OptionDescriptor> options = new LinkedHashMap<String, OptionDescriptor>();
|
||||
private Map<String, MessageDescriptor> messages = new LinkedHashMap<String, MessageDescriptor>();
|
||||
private Map<String, EnumDescriptor> enums = new LinkedHashMap<String, EnumDescriptor>();
|
||||
private List<MessageDescriptor> extendsList = new ArrayList<MessageDescriptor>();
|
||||
private Map<String, ServiceDescriptor> services = new LinkedHashMap<String, ServiceDescriptor>();
|
||||
List<String> imports = new ArrayList<String>();
|
||||
Map<String,ProtoDescriptor> importProtoDescriptors = new LinkedHashMap<String, ProtoDescriptor>();
|
||||
private String name;
|
||||
|
||||
public void setPackageName(String packageName) {
|
||||
this.packageName = packageName;
|
||||
}
|
||||
|
||||
public void setOptions(Map<String,OptionDescriptor> options) {
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
public void setMessages(Map<String,MessageDescriptor> messages) {
|
||||
this.messages = messages;
|
||||
}
|
||||
|
||||
public void setEnums(Map<String,EnumDescriptor> enums) {
|
||||
this.enums = enums;
|
||||
}
|
||||
|
||||
public void setExtends(List<MessageDescriptor> extendsList) {
|
||||
this.extendsList = extendsList;
|
||||
}
|
||||
|
||||
public List<MessageDescriptor> getExtends() {
|
||||
return extendsList;
|
||||
}
|
||||
|
||||
public String getPackageName() {
|
||||
return packageName;
|
||||
}
|
||||
|
||||
public Map<String, OptionDescriptor> getOptions() {
|
||||
return options;
|
||||
}
|
||||
|
||||
public Map<String,MessageDescriptor> getMessages() {
|
||||
return messages;
|
||||
}
|
||||
|
||||
public Map<String,EnumDescriptor> getEnums() {
|
||||
return enums;
|
||||
}
|
||||
|
||||
public void setServices(Map<String,ServiceDescriptor> services) {
|
||||
this.services = services;
|
||||
}
|
||||
|
||||
public Map<String,ServiceDescriptor> getServices() {
|
||||
return services;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for validation errors in the proto definition and fills them
|
||||
* into the errors list.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public void validate(List<String> errors) {
|
||||
for (ProtoDescriptor o : importProtoDescriptors.values()) {
|
||||
o.validate(errors);
|
||||
}
|
||||
for (OptionDescriptor o : options.values()) {
|
||||
o.validate(errors);
|
||||
}
|
||||
for (MessageDescriptor o : messages.values()) {
|
||||
o.validate(errors);
|
||||
}
|
||||
for (EnumDescriptor o : enums.values()) {
|
||||
o.validate(errors);
|
||||
}
|
||||
for (MessageDescriptor o : extendsList) {
|
||||
o.validate(errors);
|
||||
}
|
||||
for (ServiceDescriptor o : services.values()) {
|
||||
o.validate(errors);
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getImports() {
|
||||
return imports;
|
||||
}
|
||||
|
||||
public void setImports(List<String> imports) {
|
||||
this.imports = imports;
|
||||
}
|
||||
|
||||
public Map<String, ProtoDescriptor> getImportProtoDescriptors() {
|
||||
return importProtoDescriptors;
|
||||
}
|
||||
|
||||
public void setImportProtoDescriptors(Map<String, ProtoDescriptor> importProtoDescriptors) {
|
||||
this.importProtoDescriptors = importProtoDescriptors;
|
||||
}
|
||||
|
||||
public TypeDescriptor getType(String type) {
|
||||
for (MessageDescriptor o : messages.values()) {
|
||||
if( type.equals(o.getName()) ) {
|
||||
return o;
|
||||
}
|
||||
if( type.startsWith(o.getName()+".") ) {
|
||||
return o.getType( type.substring(o.getName().length()+1) );
|
||||
}
|
||||
}
|
||||
for (EnumDescriptor o : enums.values()) {
|
||||
if( type.equals(o.getName()) ) {
|
||||
return o;
|
||||
}
|
||||
}
|
||||
// Check to see if the type was qualified with the package name...
|
||||
for (ProtoDescriptor o : importProtoDescriptors.values()) {
|
||||
if( o.getPackageName()!=null && type.startsWith(o.getPackageName()+".") ) {
|
||||
return o.getType( type.substring(o.getPackageName().length()+1) );
|
||||
}
|
||||
}
|
||||
for (ProtoDescriptor o : importProtoDescriptors.values()) {
|
||||
TypeDescriptor rc = o.getType(type);
|
||||
if (rc != null) {
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.activemq.protobuf.compiler;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.activemq.protobuf.compiler.parser.ParseException;
|
||||
import org.apache.maven.plugin.AbstractMojo;
|
||||
import org.apache.maven.plugin.MojoExecutionException;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
|
||||
/**
|
||||
* A Maven Mojo so that the Proto compiler can be used with maven.
|
||||
*
|
||||
* @goal compile
|
||||
* @phase process-sources
|
||||
*/
|
||||
public class ProtoMojo extends AbstractMojo {
|
||||
|
||||
/**
|
||||
* The maven project.
|
||||
*
|
||||
* @parameter expression="${project}"
|
||||
* @required
|
||||
* @readonly
|
||||
*/
|
||||
protected MavenProject project;
|
||||
|
||||
/**
|
||||
* The directory where the proto files (<code>*.proto</code>) are
|
||||
* located.
|
||||
*
|
||||
* @parameter expression="${sourceDirectory}" default-value="${basedir}/src/main/proto"
|
||||
*/
|
||||
private File sourceDirectory;
|
||||
|
||||
/**
|
||||
* The directory where the output files will be located.
|
||||
*
|
||||
* @parameter expression="${outputDirectory}" default-value="${project.build.directory}/generated-sources/proto"
|
||||
*/
|
||||
private File outputDirectory;
|
||||
|
||||
/**
|
||||
* The type of generator to run.
|
||||
*
|
||||
* @parameter default-value="default"
|
||||
*/
|
||||
private String type;
|
||||
|
||||
public void execute() throws MojoExecutionException {
|
||||
|
||||
File[] files = sourceDirectory.listFiles(new FileFilter() {
|
||||
public boolean accept(File pathname) {
|
||||
return pathname.getName().endsWith(".proto");
|
||||
}
|
||||
});
|
||||
|
||||
if (files==null || files.length==0) {
|
||||
getLog().warn("No proto files found in directory: " + sourceDirectory.getPath());
|
||||
return;
|
||||
}
|
||||
|
||||
List<File> recFiles = Arrays.asList(files);
|
||||
for (File file : recFiles) {
|
||||
try {
|
||||
getLog().info("Compiling: "+file.getPath());
|
||||
if( "default".equals(type) ) {
|
||||
JavaGenerator generator = new JavaGenerator();
|
||||
generator.setOut(outputDirectory);
|
||||
generator.compile(file);
|
||||
} else if( "alt".equals(type) ) {
|
||||
AltJavaGenerator generator = new AltJavaGenerator();
|
||||
generator.setOut(outputDirectory);
|
||||
generator.compile(file);
|
||||
}
|
||||
} catch (CompilerException e) {
|
||||
getLog().error("Protocol Buffer Compiler failed with the following error(s):");
|
||||
for (String error : e.getErrors() ) {
|
||||
getLog().error("");
|
||||
getLog().error(error);
|
||||
}
|
||||
getLog().error("");
|
||||
throw new MojoExecutionException("Compile failed. For more details see error messages listed above.", e);
|
||||
}
|
||||
}
|
||||
|
||||
this.project.addCompileSourceRoot(outputDirectory.getAbsolutePath());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.activemq.protobuf.compiler;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ServiceDescriptor {
|
||||
|
||||
private final ProtoDescriptor protoDescriptor;
|
||||
private List<MethodDescriptor> methods=new ArrayList<MethodDescriptor>();
|
||||
private String name;
|
||||
|
||||
public ServiceDescriptor(ProtoDescriptor protoDescriptor) {
|
||||
this.protoDescriptor = protoDescriptor;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setMethods(List<MethodDescriptor> methods) {
|
||||
this.methods = methods;
|
||||
}
|
||||
|
||||
public ProtoDescriptor getProtoDescriptor() {
|
||||
return protoDescriptor;
|
||||
}
|
||||
|
||||
public List<MethodDescriptor> getMethods() {
|
||||
return methods;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void validate(List<String> errors) {
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,767 @@
|
|||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc.
|
||||
// http://code.google.com/p/protobuf/
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package org.apache.activemq.protobuf.compiler;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.CharBuffer;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.activemq.protobuf.Buffer;
|
||||
import org.apache.activemq.protobuf.UTF8Buffer;
|
||||
|
||||
/**
|
||||
* Provide ascii text parsing and formatting support for proto2 instances.
|
||||
* The implementation largely follows google/protobuf/text_format.cc.
|
||||
*
|
||||
* HRC: I wish the original class was not package protected so we did not need
|
||||
* to copy this file over. We need to request that the protobuf folks open
|
||||
* this class up amoung a few others.
|
||||
*
|
||||
* @author wenboz@google.com Wenbo Zhu
|
||||
* @author kenton@google.com Kenton Varda
|
||||
*/
|
||||
public final class TextFormat {
|
||||
|
||||
/** Convert an unsigned 32-bit integer to a string. */
|
||||
private static String unsignedToString(int value) {
|
||||
if (value >= 0) {
|
||||
return Integer.toString(value);
|
||||
} else {
|
||||
return Long.toString(((long) value) & 0x00000000FFFFFFFFL);
|
||||
}
|
||||
}
|
||||
|
||||
/** Convert an unsigned 64-bit integer to a string. */
|
||||
private static String unsignedToString(long value) {
|
||||
if (value >= 0) {
|
||||
return Long.toString(value);
|
||||
} else {
|
||||
// Pull off the most-significant bit so that BigInteger doesn't think
|
||||
// the number is negative, then set it again using setBit().
|
||||
return BigInteger.valueOf(value & 0x7FFFFFFFFFFFFFFFL)
|
||||
.setBit(63).toString();
|
||||
}
|
||||
}
|
||||
|
||||
// =================================================================
|
||||
// Parsing
|
||||
|
||||
/**
|
||||
* Represents a stream of tokens parsed from a {@code String}.
|
||||
*
|
||||
* <p>The Java standard library provides many classes that you might think
|
||||
* would be useful for implementing this, but aren't. For example:
|
||||
*
|
||||
* <ul>
|
||||
* <li>{@code java.io.StreamTokenizer}: This almost does what we want -- or,
|
||||
* at least, something that would get us close to what we want -- except
|
||||
* for one fatal flaw: It automatically un-escapes strings using Java
|
||||
* escape sequences, which do not include all the escape sequences we
|
||||
* need to support (e.g. '\x').
|
||||
* <li>{@code java.util.Scanner}: This seems like a great way at least to
|
||||
* parse regular expressions out of a stream (so we wouldn't have to load
|
||||
* the entire input into a single string before parsing). Sadly,
|
||||
* {@code Scanner} requires that tokens be delimited with some delimiter.
|
||||
* Thus, although the text "foo:" should parse to two tokens ("foo" and
|
||||
* ":"), {@code Scanner} would recognize it only as a single token.
|
||||
* Furthermore, {@code Scanner} provides no way to inspect the contents
|
||||
* of delimiters, making it impossible to keep track of line and column
|
||||
* numbers.
|
||||
* </ul>
|
||||
*
|
||||
* <p>Luckily, Java's regular expression support does manage to be useful to
|
||||
* us. (Barely: We need {@code Matcher.usePattern()}, which is new in
|
||||
* Java 1.5.) So, we can use that, at least. Unfortunately, this implies
|
||||
* that we need to have the entire input in one contiguous string.
|
||||
*/
|
||||
private static final class Tokenizer {
|
||||
private final CharSequence text;
|
||||
private final Matcher matcher;
|
||||
private String currentToken;
|
||||
|
||||
// The character index within this.text at which the current token begins.
|
||||
private int pos = 0;
|
||||
|
||||
// The line and column numbers of the current token.
|
||||
private int line = 0;
|
||||
private int column = 0;
|
||||
|
||||
// The line and column numbers of the previous token (allows throwing
|
||||
// errors *after* consuming).
|
||||
private int previousLine = 0;
|
||||
private int previousColumn = 0;
|
||||
|
||||
private static Pattern WHITESPACE =
|
||||
Pattern.compile("(\\s|(#.*$))+", Pattern.MULTILINE);
|
||||
private static Pattern TOKEN = Pattern.compile(
|
||||
"[a-zA-Z_][0-9a-zA-Z_+-]*|" + // an identifier
|
||||
"[0-9+-][0-9a-zA-Z_.+-]*|" + // a number
|
||||
"\"([^\"\n\\\\]|\\\\.)*(\"|\\\\?$)|" + // a double-quoted string
|
||||
"\'([^\"\n\\\\]|\\\\.)*(\'|\\\\?$)", // a single-quoted string
|
||||
Pattern.MULTILINE);
|
||||
|
||||
private static Pattern DOUBLE_INFINITY = Pattern.compile(
|
||||
"-?inf(inity)?",
|
||||
Pattern.CASE_INSENSITIVE);
|
||||
private static Pattern FLOAT_INFINITY = Pattern.compile(
|
||||
"-?inf(inity)?f?",
|
||||
Pattern.CASE_INSENSITIVE);
|
||||
private static Pattern FLOAT_NAN = Pattern.compile(
|
||||
"nanf?",
|
||||
Pattern.CASE_INSENSITIVE);
|
||||
|
||||
/** Construct a tokenizer that parses tokens from the given text. */
|
||||
public Tokenizer(CharSequence text) {
|
||||
this.text = text;
|
||||
this.matcher = WHITESPACE.matcher(text);
|
||||
skipWhitespace();
|
||||
nextToken();
|
||||
}
|
||||
|
||||
/** Are we at the end of the input? */
|
||||
public boolean atEnd() {
|
||||
return currentToken.length() == 0;
|
||||
}
|
||||
|
||||
/** Advance to the next token. */
|
||||
public void nextToken() {
|
||||
previousLine = line;
|
||||
previousColumn = column;
|
||||
|
||||
// Advance the line counter to the current position.
|
||||
while (pos < matcher.regionStart()) {
|
||||
if (text.charAt(pos) == '\n') {
|
||||
++line;
|
||||
column = 0;
|
||||
} else {
|
||||
++column;
|
||||
}
|
||||
++pos;
|
||||
}
|
||||
|
||||
// Match the next token.
|
||||
if (matcher.regionStart() == matcher.regionEnd()) {
|
||||
// EOF
|
||||
currentToken = "";
|
||||
} else {
|
||||
matcher.usePattern(TOKEN);
|
||||
if (matcher.lookingAt()) {
|
||||
currentToken = matcher.group();
|
||||
matcher.region(matcher.end(), matcher.regionEnd());
|
||||
} else {
|
||||
// Take one character.
|
||||
currentToken = String.valueOf(text.charAt(pos));
|
||||
matcher.region(pos + 1, matcher.regionEnd());
|
||||
}
|
||||
|
||||
skipWhitespace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip over any whitespace so that the matcher region starts at the next
|
||||
* token.
|
||||
*/
|
||||
private void skipWhitespace() {
|
||||
matcher.usePattern(WHITESPACE);
|
||||
if (matcher.lookingAt()) {
|
||||
matcher.region(matcher.end(), matcher.regionEnd());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the next token exactly matches {@code token}, consume it and return
|
||||
* {@code true}. Otherwise, return {@code false} without doing anything.
|
||||
*/
|
||||
public boolean tryConsume(String token) {
|
||||
if (currentToken.equals(token)) {
|
||||
nextToken();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the next token exactly matches {@code token}, consume it. Otherwise,
|
||||
* throw a {@link ParseException}.
|
||||
*/
|
||||
public void consume(String token) throws ParseException {
|
||||
if (!tryConsume(token)) {
|
||||
throw parseException("Expected \"" + token + "\".");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the next token is an integer, but does
|
||||
* not consume it.
|
||||
*/
|
||||
public boolean lookingAtInteger() {
|
||||
if (currentToken.length() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
char c = currentToken.charAt(0);
|
||||
return ('0' <= c && c <= '9') ||
|
||||
c == '-' || c == '+';
|
||||
}
|
||||
|
||||
/**
|
||||
* If the next token is an identifier, consume it and return its value.
|
||||
* Otherwise, throw a {@link ParseException}.
|
||||
*/
|
||||
public String consumeIdentifier() throws ParseException {
|
||||
for (int i = 0; i < currentToken.length(); i++) {
|
||||
char c = currentToken.charAt(i);
|
||||
if (('a' <= c && c <= 'z') ||
|
||||
('A' <= c && c <= 'Z') ||
|
||||
('0' <= c && c <= '9') ||
|
||||
(c == '_') || (c == '.')) {
|
||||
// OK
|
||||
} else {
|
||||
throw parseException("Expected identifier.");
|
||||
}
|
||||
}
|
||||
|
||||
String result = currentToken;
|
||||
nextToken();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the next token is a 32-bit signed integer, consume it and return its
|
||||
* value. Otherwise, throw a {@link ParseException}.
|
||||
*/
|
||||
public int consumeInt32() throws ParseException {
|
||||
try {
|
||||
int result = parseInt32(currentToken);
|
||||
nextToken();
|
||||
return result;
|
||||
} catch (NumberFormatException e) {
|
||||
throw integerParseException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the next token is a 32-bit unsigned integer, consume it and return its
|
||||
* value. Otherwise, throw a {@link ParseException}.
|
||||
*/
|
||||
public int consumeUInt32() throws ParseException {
|
||||
try {
|
||||
int result = parseUInt32(currentToken);
|
||||
nextToken();
|
||||
return result;
|
||||
} catch (NumberFormatException e) {
|
||||
throw integerParseException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the next token is a 64-bit signed integer, consume it and return its
|
||||
* value. Otherwise, throw a {@link ParseException}.
|
||||
*/
|
||||
public long consumeInt64() throws ParseException {
|
||||
try {
|
||||
long result = parseInt64(currentToken);
|
||||
nextToken();
|
||||
return result;
|
||||
} catch (NumberFormatException e) {
|
||||
throw integerParseException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the next token is a 64-bit unsigned integer, consume it and return its
|
||||
* value. Otherwise, throw a {@link ParseException}.
|
||||
*/
|
||||
public long consumeUInt64() throws ParseException {
|
||||
try {
|
||||
long result = parseUInt64(currentToken);
|
||||
nextToken();
|
||||
return result;
|
||||
} catch (NumberFormatException e) {
|
||||
throw integerParseException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the next token is a double, consume it and return its value.
|
||||
* Otherwise, throw a {@link ParseException}.
|
||||
*/
|
||||
public double consumeDouble() throws ParseException {
|
||||
// We need to parse infinity and nan separately because
|
||||
// Double.parseDouble() does not accept "inf", "infinity", or "nan".
|
||||
if (DOUBLE_INFINITY.matcher(currentToken).matches()) {
|
||||
boolean negative = currentToken.startsWith("-");
|
||||
nextToken();
|
||||
return negative ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
|
||||
}
|
||||
if (currentToken.equalsIgnoreCase("nan")) {
|
||||
nextToken();
|
||||
return Double.NaN;
|
||||
}
|
||||
try {
|
||||
double result = Double.parseDouble(currentToken);
|
||||
nextToken();
|
||||
return result;
|
||||
} catch (NumberFormatException e) {
|
||||
throw floatParseException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the next token is a float, consume it and return its value.
|
||||
* Otherwise, throw a {@link ParseException}.
|
||||
*/
|
||||
public float consumeFloat() throws ParseException {
|
||||
// We need to parse infinity and nan separately because
|
||||
// Float.parseFloat() does not accept "inf", "infinity", or "nan".
|
||||
if (FLOAT_INFINITY.matcher(currentToken).matches()) {
|
||||
boolean negative = currentToken.startsWith("-");
|
||||
nextToken();
|
||||
return negative ? Float.NEGATIVE_INFINITY : Float.POSITIVE_INFINITY;
|
||||
}
|
||||
if (FLOAT_NAN.matcher(currentToken).matches()) {
|
||||
nextToken();
|
||||
return Float.NaN;
|
||||
}
|
||||
try {
|
||||
float result = Float.parseFloat(currentToken);
|
||||
nextToken();
|
||||
return result;
|
||||
} catch (NumberFormatException e) {
|
||||
throw floatParseException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the next token is a boolean, consume it and return its value.
|
||||
* Otherwise, throw a {@link ParseException}.
|
||||
*/
|
||||
public boolean consumeBoolean() throws ParseException {
|
||||
if (currentToken.equals("true")) {
|
||||
nextToken();
|
||||
return true;
|
||||
} else if (currentToken.equals("false")) {
|
||||
nextToken();
|
||||
return false;
|
||||
} else {
|
||||
throw parseException("Expected \"true\" or \"false\".");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the next token is a string, consume it and return its (unescaped)
|
||||
* value. Otherwise, throw a {@link ParseException}.
|
||||
*/
|
||||
public String consumeString() throws ParseException {
|
||||
return new UTF8Buffer(consumeBuffer()).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* If the next token is a string, consume it, unescape it as a
|
||||
* {@link Buffer}, and return it. Otherwise, throw a
|
||||
* {@link ParseException}.
|
||||
*/
|
||||
public Buffer consumeBuffer() throws ParseException {
|
||||
char quote = currentToken.length() > 0 ? currentToken.charAt(0) : '\0';
|
||||
if (quote != '\"' && quote != '\'') {
|
||||
throw parseException("Expected string.");
|
||||
}
|
||||
|
||||
if (currentToken.length() < 2 ||
|
||||
currentToken.charAt(currentToken.length() - 1) != quote) {
|
||||
throw parseException("String missing ending quote.");
|
||||
}
|
||||
|
||||
try {
|
||||
String escaped = currentToken.substring(1, currentToken.length() - 1);
|
||||
Buffer result = unescapeBytes(escaped);
|
||||
nextToken();
|
||||
return result;
|
||||
} catch (InvalidEscapeSequence e) {
|
||||
throw parseException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link ParseException} with the current line and column
|
||||
* numbers in the description, suitable for throwing.
|
||||
*/
|
||||
public ParseException parseException(String description) {
|
||||
// Note: People generally prefer one-based line and column numbers.
|
||||
return new ParseException(
|
||||
(line + 1) + ":" + (column + 1) + ": " + description);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link ParseException} with the line and column numbers of
|
||||
* the previous token in the description, suitable for throwing.
|
||||
*/
|
||||
public ParseException parseExceptionPreviousToken(String description) {
|
||||
// Note: People generally prefer one-based line and column numbers.
|
||||
return new ParseException(
|
||||
(previousLine + 1) + ":" + (previousColumn + 1) + ": " + description);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an appropriate {@link ParseException} for the given
|
||||
* {@code NumberFormatException} when trying to parse an integer.
|
||||
*/
|
||||
private ParseException integerParseException(NumberFormatException e) {
|
||||
return parseException("Couldn't parse integer: " + e.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an appropriate {@link ParseException} for the given
|
||||
* {@code NumberFormatException} when trying to parse a float or double.
|
||||
*/
|
||||
private ParseException floatParseException(NumberFormatException e) {
|
||||
return parseException("Couldn't parse number: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/** Thrown when parsing an invalid text format message. */
|
||||
public static class ParseException extends IOException {
|
||||
public ParseException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
||||
private static final int BUFFER_SIZE = 4096;
|
||||
|
||||
// TODO(chrisn): See if working around java.io.Reader#read(CharBuffer)
|
||||
// overhead is worthwhile
|
||||
private static StringBuilder toStringBuilder(Readable input)
|
||||
throws IOException {
|
||||
StringBuilder text = new StringBuilder();
|
||||
CharBuffer buffer = CharBuffer.allocate(BUFFER_SIZE);
|
||||
while (true) {
|
||||
int n = input.read(buffer);
|
||||
if (n == -1) {
|
||||
break;
|
||||
}
|
||||
buffer.flip();
|
||||
text.append(buffer, 0, n);
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
|
||||
// =================================================================
|
||||
// Utility functions
|
||||
//
|
||||
// Some of these methods are package-private because Descriptors.java uses
|
||||
// them.
|
||||
|
||||
/**
|
||||
* Escapes bytes in the format used in protocol buffer text format, which
|
||||
* is the same as the format used for C string literals. All bytes
|
||||
* that are not printable 7-bit ASCII characters are escaped, as well as
|
||||
* backslash, single-quote, and double-quote characters. Characters for
|
||||
* which no defined short-hand escape sequence is defined will be escaped
|
||||
* using 3-digit octal sequences.
|
||||
*/
|
||||
static String escapeBytes(Buffer input) {
|
||||
StringBuilder builder = new StringBuilder(input.getLength());
|
||||
for (int i = 0; i < input.getLength(); i++) {
|
||||
byte b = input.byteAt(i);
|
||||
switch (b) {
|
||||
// Java does not recognize \a or \v, apparently.
|
||||
case 0x07: builder.append("\\a" ); break;
|
||||
case '\b': builder.append("\\b" ); break;
|
||||
case '\f': builder.append("\\f" ); break;
|
||||
case '\n': builder.append("\\n" ); break;
|
||||
case '\r': builder.append("\\r" ); break;
|
||||
case '\t': builder.append("\\t" ); break;
|
||||
case 0x0b: builder.append("\\v" ); break;
|
||||
case '\\': builder.append("\\\\"); break;
|
||||
case '\'': builder.append("\\\'"); break;
|
||||
case '"' : builder.append("\\\""); break;
|
||||
default:
|
||||
if (b >= 0x20) {
|
||||
builder.append((char) b);
|
||||
} else {
|
||||
builder.append('\\');
|
||||
builder.append((char) ('0' + ((b >>> 6) & 3)));
|
||||
builder.append((char) ('0' + ((b >>> 3) & 7)));
|
||||
builder.append((char) ('0' + (b & 7)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Un-escape a byte sequence as escaped using
|
||||
* {@link #escapeBytes(Buffer)}. Two-digit hex escapes (starting with
|
||||
* "\x") are also recognized.
|
||||
*/
|
||||
static Buffer unescapeBytes(CharSequence input)
|
||||
throws InvalidEscapeSequence {
|
||||
byte[] result = new byte[input.length()];
|
||||
int pos = 0;
|
||||
for (int i = 0; i < input.length(); i++) {
|
||||
char c = input.charAt(i);
|
||||
if (c == '\\') {
|
||||
if (i + 1 < input.length()) {
|
||||
++i;
|
||||
c = input.charAt(i);
|
||||
if (isOctal(c)) {
|
||||
// Octal escape.
|
||||
int code = digitValue(c);
|
||||
if (i + 1 < input.length() && isOctal(input.charAt(i + 1))) {
|
||||
++i;
|
||||
code = code * 8 + digitValue(input.charAt(i));
|
||||
}
|
||||
if (i + 1 < input.length() && isOctal(input.charAt(i + 1))) {
|
||||
++i;
|
||||
code = code * 8 + digitValue(input.charAt(i));
|
||||
}
|
||||
result[pos++] = (byte)code;
|
||||
} else {
|
||||
switch (c) {
|
||||
case 'a' : result[pos++] = 0x07; break;
|
||||
case 'b' : result[pos++] = '\b'; break;
|
||||
case 'f' : result[pos++] = '\f'; break;
|
||||
case 'n' : result[pos++] = '\n'; break;
|
||||
case 'r' : result[pos++] = '\r'; break;
|
||||
case 't' : result[pos++] = '\t'; break;
|
||||
case 'v' : result[pos++] = 0x0b; break;
|
||||
case '\\': result[pos++] = '\\'; break;
|
||||
case '\'': result[pos++] = '\''; break;
|
||||
case '"' : result[pos++] = '\"'; break;
|
||||
|
||||
case 'x':
|
||||
// hex escape
|
||||
int code = 0;
|
||||
if (i + 1 < input.length() && isHex(input.charAt(i + 1))) {
|
||||
++i;
|
||||
code = digitValue(input.charAt(i));
|
||||
} else {
|
||||
throw new InvalidEscapeSequence(
|
||||
"Invalid escape sequence: '\\x' with no digits");
|
||||
}
|
||||
if (i + 1 < input.length() && isHex(input.charAt(i + 1))) {
|
||||
++i;
|
||||
code = code * 16 + digitValue(input.charAt(i));
|
||||
}
|
||||
result[pos++] = (byte)code;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new InvalidEscapeSequence(
|
||||
"Invalid escape sequence: '\\" + c + "'");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new InvalidEscapeSequence(
|
||||
"Invalid escape sequence: '\\' at end of string.");
|
||||
}
|
||||
} else {
|
||||
result[pos++] = (byte)c;
|
||||
}
|
||||
}
|
||||
|
||||
return new Buffer(result, 0, pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Thrown by {@link TextFormat#unescapeBytes} and
|
||||
* {@link TextFormat#unescapeText} when an invalid escape sequence is seen.
|
||||
*/
|
||||
static class InvalidEscapeSequence extends IOException {
|
||||
public InvalidEscapeSequence(String description) {
|
||||
super(description);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Like {@link #escapeBytes(Buffer)}, but escapes a text string.
|
||||
* Non-ASCII characters are first encoded as UTF-8, then each byte is escaped
|
||||
* individually as a 3-digit octal escape. Yes, it's weird.
|
||||
*/
|
||||
static String escapeText(String input) {
|
||||
return escapeBytes(new UTF8Buffer(input));
|
||||
}
|
||||
|
||||
/**
|
||||
* Un-escape a text string as escaped using {@link #escapeText(String)}.
|
||||
* Two-digit hex escapes (starting with "\x") are also recognized.
|
||||
*/
|
||||
static String unescapeText(String input) throws InvalidEscapeSequence {
|
||||
return new UTF8Buffer(unescapeBytes(input)).toString();
|
||||
}
|
||||
|
||||
/** Is this an octal digit? */
|
||||
private static boolean isOctal(char c) {
|
||||
return '0' <= c && c <= '7';
|
||||
}
|
||||
|
||||
/** Is this a hex digit? */
|
||||
private static boolean isHex(char c) {
|
||||
return ('0' <= c && c <= '9') ||
|
||||
('a' <= c && c <= 'f') ||
|
||||
('A' <= c && c <= 'F');
|
||||
}
|
||||
|
||||
/**
|
||||
* Interpret a character as a digit (in any base up to 36) and return the
|
||||
* numeric value. This is like {@code Character.digit()} but we don't accept
|
||||
* non-ASCII digits.
|
||||
*/
|
||||
private static int digitValue(char c) {
|
||||
if ('0' <= c && c <= '9') {
|
||||
return c - '0';
|
||||
} else if ('a' <= c && c <= 'z') {
|
||||
return c - 'a' + 10;
|
||||
} else {
|
||||
return c - 'A' + 10;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a 32-bit signed integer from the text. Unlike the Java standard
|
||||
* {@code Integer.parseInt()}, this function recognizes the prefixes "0x"
|
||||
* and "0" to signify hexidecimal and octal numbers, respectively.
|
||||
*/
|
||||
static int parseInt32(String text) throws NumberFormatException {
|
||||
return (int) parseInteger(text, true, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a 32-bit unsigned integer from the text. Unlike the Java standard
|
||||
* {@code Integer.parseInt()}, this function recognizes the prefixes "0x"
|
||||
* and "0" to signify hexidecimal and octal numbers, respectively. The
|
||||
* result is coerced to a (signed) {@code int} when returned since Java has
|
||||
* no unsigned integer type.
|
||||
*/
|
||||
static int parseUInt32(String text) throws NumberFormatException {
|
||||
return (int) parseInteger(text, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a 64-bit signed integer from the text. Unlike the Java standard
|
||||
* {@code Integer.parseInt()}, this function recognizes the prefixes "0x"
|
||||
* and "0" to signify hexidecimal and octal numbers, respectively.
|
||||
*/
|
||||
static long parseInt64(String text) throws NumberFormatException {
|
||||
return parseInteger(text, true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a 64-bit unsigned integer from the text. Unlike the Java standard
|
||||
* {@code Integer.parseInt()}, this function recognizes the prefixes "0x"
|
||||
* and "0" to signify hexidecimal and octal numbers, respectively. The
|
||||
* result is coerced to a (signed) {@code long} when returned since Java has
|
||||
* no unsigned long type.
|
||||
*/
|
||||
static long parseUInt64(String text) throws NumberFormatException {
|
||||
return parseInteger(text, false, true);
|
||||
}
|
||||
|
||||
private static long parseInteger(String text,
|
||||
boolean isSigned,
|
||||
boolean isLong)
|
||||
throws NumberFormatException {
|
||||
int pos = 0;
|
||||
|
||||
boolean negative = false;
|
||||
if (text.startsWith("-", pos)) {
|
||||
if (!isSigned) {
|
||||
throw new NumberFormatException("Number must be positive: " + text);
|
||||
}
|
||||
++pos;
|
||||
negative = true;
|
||||
}
|
||||
|
||||
int radix = 10;
|
||||
if (text.startsWith("0x", pos)) {
|
||||
pos += 2;
|
||||
radix = 16;
|
||||
} else if (text.startsWith("0", pos)) {
|
||||
radix = 8;
|
||||
}
|
||||
|
||||
String numberText = text.substring(pos);
|
||||
|
||||
long result = 0;
|
||||
if (numberText.length() < 16) {
|
||||
// Can safely assume no overflow.
|
||||
result = Long.parseLong(numberText, radix);
|
||||
if (negative) {
|
||||
result = -result;
|
||||
}
|
||||
|
||||
// Check bounds.
|
||||
// No need to check for 64-bit numbers since they'd have to be 16 chars
|
||||
// or longer to overflow.
|
||||
if (!isLong) {
|
||||
if (isSigned) {
|
||||
if (result > Integer.MAX_VALUE || result < Integer.MIN_VALUE) {
|
||||
throw new NumberFormatException(
|
||||
"Number out of range for 32-bit signed integer: " + text);
|
||||
}
|
||||
} else {
|
||||
if (result >= (1L << 32) || result < 0) {
|
||||
throw new NumberFormatException(
|
||||
"Number out of range for 32-bit unsigned integer: " + text);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
BigInteger bigValue = new BigInteger(numberText, radix);
|
||||
if (negative) {
|
||||
bigValue = bigValue.negate();
|
||||
}
|
||||
|
||||
// Check bounds.
|
||||
if (!isLong) {
|
||||
if (isSigned) {
|
||||
if (bigValue.bitLength() > 31) {
|
||||
throw new NumberFormatException(
|
||||
"Number out of range for 32-bit signed integer: " + text);
|
||||
}
|
||||
} else {
|
||||
if (bigValue.bitLength() > 32) {
|
||||
throw new NumberFormatException(
|
||||
"Number out of range for 32-bit unsigned integer: " + text);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (isSigned) {
|
||||
if (bigValue.bitLength() > 63) {
|
||||
throw new NumberFormatException(
|
||||
"Number out of range for 64-bit signed integer: " + text);
|
||||
}
|
||||
} else {
|
||||
if (bigValue.bitLength() > 64) {
|
||||
throw new NumberFormatException(
|
||||
"Number out of range for 64-bit unsigned integer: " + text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result = bigValue.longValue();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.activemq.protobuf.compiler;
|
||||
|
||||
public interface TypeDescriptor {
|
||||
public String getName();
|
||||
|
||||
public String getQName();
|
||||
|
||||
public ProtoDescriptor getProtoDescriptor();
|
||||
|
||||
public boolean isEnum();
|
||||
|
||||
public void associate(EnumFieldDescriptor desc);
|
||||
|
||||
}
|
|
@ -0,0 +1,599 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
options {
|
||||
STATIC=false;
|
||||
}
|
||||
|
||||
PARSER_BEGIN(ProtoParser)
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.activemq.protobuf.compiler.parser;
|
||||
|
||||
import org.apache.activemq.protobuf.compiler.*;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Iterator;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* This class is generated with JavaCC. Do not modify manually.
|
||||
*/
|
||||
public class ProtoParser {
|
||||
}
|
||||
|
||||
PARSER_END(ProtoParser)
|
||||
|
||||
SKIP :
|
||||
{
|
||||
" "
|
||||
| "\t"
|
||||
| "\n"
|
||||
| "\r"
|
||||
}
|
||||
|
||||
SPECIAL_TOKEN :
|
||||
{
|
||||
"//" : COMMENT
|
||||
}
|
||||
|
||||
<COMMENT> SPECIAL_TOKEN :
|
||||
{
|
||||
<("\n" | "\r" | "\r\n" | "|")> : DEFAULT
|
||||
}
|
||||
|
||||
<COMMENT> MORE :
|
||||
{
|
||||
<~[]>
|
||||
}
|
||||
|
||||
TOKEN :
|
||||
{
|
||||
<IMPORT:"import">
|
||||
| <PACKAGE:"package">
|
||||
| <SERVICE:"service">
|
||||
| <RPC:"rpc">
|
||||
| <OPTION:"option">
|
||||
| <MESSAGE:"message">
|
||||
| <EXTENSIONS:"extensions">
|
||||
| <EXTEND:"extend">
|
||||
| <ENUM:"enum">
|
||||
| <GROUP:"group">
|
||||
| <REQURIED:"required">
|
||||
| <OPTIONAL:"optional">
|
||||
| <REPEATED:"repeated">
|
||||
| <RETURNS:"returns">
|
||||
| <TO:"to">
|
||||
| <MAX:"max">
|
||||
|
||||
| <LBRACE: "{">
|
||||
| <RBRACE: "}">
|
||||
| <EQUALS: "=">
|
||||
| <SEMICOLON: ";">
|
||||
| <LBRACKET: "[">
|
||||
| <RBRACKET: "]">
|
||||
| <LPAREN: "(">
|
||||
| <RPAREN: ")">
|
||||
| <PERIOD: ".">
|
||||
| <COMMA: ",">
|
||||
|
||||
| < INTEGER: ("-")? (
|
||||
<DECIMAL_LITERAL> (["l","L"])?
|
||||
| <HEX_LITERAL> (["l","L"])?
|
||||
| <OCTAL_LITERAL> (["l","L"])?
|
||||
) >
|
||||
| < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* >
|
||||
| < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ >
|
||||
| < #OCTAL_LITERAL: "0" (["0"-"7"])* >
|
||||
| < FLOAT: ("-")? (
|
||||
(["0"-"9"])+ "." (["0"-"9"])* (<EXPONENT>)? (["f","F","d","D"])?
|
||||
| "." (["0"-"9"])+ (<EXPONENT>)? (["f","F","d","D"])?
|
||||
| (["0"-"9"])+ <EXPONENT> (["f","F","d","D"])?
|
||||
| (["0"-"9"])+ (<EXPONENT>)? ["f","F","d","D"]
|
||||
)>
|
||||
| < #EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
|
||||
| <STRING:
|
||||
"\""
|
||||
( (~["\"","\\","\n","\r"])
|
||||
| ("\\"
|
||||
( ["a","v","n","t","b","r","f","\\","'","\""]
|
||||
| ["x","X"]["0"-"9","A"-"F","a"-"f"]["0"-"9","A"-"F","a"-"f"]
|
||||
| ["0"-"7"] ( ["0"-"7"] )?
|
||||
| ["0"-"3"] ["0"-"7"] ["0"-"7"]
|
||||
)
|
||||
)
|
||||
)*
|
||||
"\"">
|
||||
| <ID: ["A"-"Z","a"-"z"] (["a"-"z","A"-"Z","0"-"9","_"])*>
|
||||
}
|
||||
|
||||
ProtoDescriptor ProtoDescriptor() :
|
||||
{
|
||||
ProtoDescriptor proto = new ProtoDescriptor();
|
||||
String packageName=null;
|
||||
LinkedHashMap<String,OptionDescriptor> opts = new LinkedHashMap<String,OptionDescriptor>();
|
||||
LinkedHashMap<String,MessageDescriptor> messages = new LinkedHashMap<String,MessageDescriptor>();
|
||||
LinkedHashMap<String,EnumDescriptor> enums = new LinkedHashMap<String,EnumDescriptor>();
|
||||
ArrayList<MessageDescriptor> extendsList = new ArrayList<MessageDescriptor>();
|
||||
LinkedHashMap<String,ServiceDescriptor> services = new LinkedHashMap<String,ServiceDescriptor>();
|
||||
ArrayList<String> imports = new ArrayList<String>();
|
||||
|
||||
OptionDescriptor optionD;
|
||||
MessageDescriptor messageD;
|
||||
EnumDescriptor enumD;
|
||||
ServiceDescriptor serviceD;
|
||||
MessageDescriptor extendD;
|
||||
String o;
|
||||
}
|
||||
{
|
||||
(
|
||||
<PACKAGE> packageName=PackageID() <SEMICOLON>
|
||||
|
|
||||
<OPTION> optionD = OptionDescriptor() <SEMICOLON>
|
||||
{ opts.put(optionD.getName(),optionD); }
|
||||
|
|
||||
<IMPORT>
|
||||
o = StringLitteral()
|
||||
<SEMICOLON>
|
||||
{ imports.add((String)o); }
|
||||
|
|
||||
messageD = MessageDescriptor(proto, null) (<SEMICOLON>)?
|
||||
{ messages.put(messageD.getName(),messageD); }
|
||||
|
||||
|
|
||||
enumD = EnumDescriptor(proto, null) (<SEMICOLON>)?
|
||||
{ enums.put(enumD.getName(),enumD); }
|
||||
|
|
||||
serviceD = ServiceDescriptor(proto) (<SEMICOLON>)?
|
||||
{ services.put(serviceD.getName(),serviceD); }
|
||||
|
|
||||
extendD = ExtendDescriptor(proto, null) (<SEMICOLON>)?
|
||||
{ extendsList.add(extendD); }
|
||||
)+
|
||||
<EOF>
|
||||
{
|
||||
proto.setPackageName(packageName);
|
||||
proto.setImports(imports);
|
||||
proto.setOptions(opts);
|
||||
proto.setMessages(messages);
|
||||
proto.setEnums(enums);
|
||||
proto.setServices(services);
|
||||
proto.setExtends(extendsList);
|
||||
return proto;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MessageDescriptor MessageDescriptor(ProtoDescriptor proto, MessageDescriptor parent) :
|
||||
{
|
||||
String name;
|
||||
LinkedHashMap<String,FieldDescriptor> fields = new LinkedHashMap<String,FieldDescriptor>();
|
||||
LinkedHashMap<String,MessageDescriptor> messages = new LinkedHashMap<String,MessageDescriptor>();
|
||||
LinkedHashMap<String,EnumDescriptor> enums = new LinkedHashMap<String,EnumDescriptor>();
|
||||
ArrayList<MessageDescriptor> extendsList = new ArrayList<MessageDescriptor>();
|
||||
LinkedHashMap<String,OptionDescriptor> opts = new LinkedHashMap<String,OptionDescriptor>();
|
||||
|
||||
MessageDescriptor rc = new MessageDescriptor(proto, parent);
|
||||
OptionDescriptor optionD;
|
||||
ExtensionsDescriptor extensionsD=null;
|
||||
FieldDescriptor fieldD;
|
||||
MessageDescriptor messageD;
|
||||
EnumDescriptor enumD;
|
||||
MessageDescriptor extendD;
|
||||
}
|
||||
{
|
||||
<MESSAGE> name = ID() <LBRACE>
|
||||
(
|
||||
<OPTION> optionD = OptionDescriptor() <SEMICOLON>
|
||||
{ opts.put(optionD.getName(),optionD); }
|
||||
|
|
||||
fieldD = FieldDescriptor(rc)
|
||||
{ fields.put(fieldD.getName(), fieldD); }
|
||||
|
|
||||
messageD = MessageDescriptor(proto, rc) (<SEMICOLON>)?
|
||||
{ messages.put(messageD.getName(),messageD); }
|
||||
|
|
||||
enumD = EnumDescriptor(proto, rc) (<SEMICOLON>)?
|
||||
{ enums.put(enumD.getName(), enumD); }
|
||||
|
|
||||
extensionsD = ExtensionsDescriptor(rc) <SEMICOLON>
|
||||
|
|
||||
extendD = ExtendDescriptor(proto, rc) (<SEMICOLON>)?
|
||||
{ extendsList.add(extendD); }
|
||||
)*
|
||||
<RBRACE>
|
||||
{
|
||||
rc.setName(name);
|
||||
rc.setFields(fields);
|
||||
rc.setMessages(messages);
|
||||
rc.setEnums(enums);
|
||||
rc.setExtensions(extensionsD);
|
||||
rc.setOptions(opts);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses something like:
|
||||
* optional string foo = 1;
|
||||
*/
|
||||
FieldDescriptor FieldDescriptor(MessageDescriptor parent) :
|
||||
{
|
||||
String rule;
|
||||
String type;
|
||||
String name;
|
||||
int tag;
|
||||
LinkedHashMap<String,OptionDescriptor> opts = new LinkedHashMap<String,OptionDescriptor>();
|
||||
LinkedHashMap<String,FieldDescriptor> fields = new LinkedHashMap<String,FieldDescriptor>();
|
||||
OptionDescriptor optionD;
|
||||
FieldDescriptor fieldD;
|
||||
FieldDescriptor rc = new FieldDescriptor(parent);
|
||||
MessageDescriptor group = new MessageDescriptor(parent.getProtoDescriptor(), parent);
|
||||
}
|
||||
{
|
||||
|
||||
rule = Rule()
|
||||
(
|
||||
// We have to go through the look ahead trouble because based on if 'type' is 'group'
|
||||
// we need to look ahead to see if it looks like a group declaration instead it being
|
||||
// message type called group.
|
||||
|
||||
LOOKAHEAD(5)
|
||||
type = PackageID()
|
||||
name = ID()
|
||||
<EQUALS>
|
||||
tag = Integer()
|
||||
(
|
||||
<LBRACKET>
|
||||
optionD = OptionDescriptor()
|
||||
{
|
||||
opts.put(optionD.getName(), optionD);
|
||||
}
|
||||
(
|
||||
<COMMA>
|
||||
optionD = OptionDescriptor()
|
||||
{
|
||||
opts.put(optionD.getName(), optionD);
|
||||
}
|
||||
)*
|
||||
<RBRACKET>
|
||||
)?
|
||||
<SEMICOLON>
|
||||
|
|
||||
{
|
||||
}
|
||||
<GROUP>
|
||||
name = ID()
|
||||
<EQUALS>
|
||||
tag = Integer()
|
||||
<LBRACE>
|
||||
(
|
||||
fieldD = FieldDescriptor(group)
|
||||
{
|
||||
fields.put(fieldD.getName(), fieldD);
|
||||
}
|
||||
)*
|
||||
<RBRACE>
|
||||
( <SEMICOLON> )?
|
||||
{
|
||||
type = name;
|
||||
group.setName(name);
|
||||
group.setFields(fields);
|
||||
rc.setGroup(group);
|
||||
}
|
||||
)
|
||||
{
|
||||
rc.setName(name);
|
||||
rc.setType(type);
|
||||
rc.setRule(rule);
|
||||
rc.setTag(tag);
|
||||
rc.setOptions(opts);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
ServiceDescriptor ServiceDescriptor(ProtoDescriptor proto) :
|
||||
{
|
||||
String name;
|
||||
ArrayList<MethodDescriptor> methods = new ArrayList<MethodDescriptor>();
|
||||
MethodDescriptor method;
|
||||
}
|
||||
{
|
||||
<SERVICE> name = ID() <LBRACE>
|
||||
(
|
||||
method = MethodDescriptor(proto) <SEMICOLON>
|
||||
{
|
||||
methods.add(method);
|
||||
}
|
||||
)*
|
||||
<RBRACE>
|
||||
{
|
||||
ServiceDescriptor rc = new ServiceDescriptor(proto);
|
||||
rc.setName(name);
|
||||
rc.setMethods(methods);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
MethodDescriptor MethodDescriptor(ProtoDescriptor proto) :
|
||||
{
|
||||
String name;
|
||||
String input;
|
||||
String output;
|
||||
}
|
||||
{
|
||||
<RPC> name = ID() <LPAREN> input = PackageID() <RPAREN> <RETURNS> <LPAREN> output = PackageID() <RPAREN>
|
||||
{
|
||||
MethodDescriptor rc = new MethodDescriptor(proto);
|
||||
rc.setName(name);
|
||||
rc.setParameter(input);
|
||||
rc.setReturns(output);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
OptionDescriptor OptionDescriptor() :
|
||||
{
|
||||
String name;
|
||||
String value;
|
||||
}
|
||||
{
|
||||
name = ID()
|
||||
<EQUALS>
|
||||
value=Value()
|
||||
{
|
||||
OptionDescriptor rc = new OptionDescriptor();
|
||||
rc.setName(name);
|
||||
rc.setValue(value);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
MessageDescriptor ExtendDescriptor(ProtoDescriptor proto, MessageDescriptor parent) :
|
||||
{
|
||||
String name;
|
||||
LinkedHashMap<String, FieldDescriptor> fields = new LinkedHashMap<String,FieldDescriptor>();
|
||||
MessageDescriptor rc = new MessageDescriptor(proto, parent);
|
||||
FieldDescriptor fieldD;
|
||||
}
|
||||
{
|
||||
<EXTEND> name = ID() <LBRACE>
|
||||
(
|
||||
fieldD = FieldDescriptor(rc)
|
||||
{ fields.put(fieldD.getName(), fieldD); }
|
||||
)*
|
||||
<RBRACE>
|
||||
{
|
||||
rc.setName(name);
|
||||
rc.setFields(fields);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
ExtensionsDescriptor ExtensionsDescriptor(MessageDescriptor parent) :
|
||||
{
|
||||
int first;
|
||||
int last;
|
||||
}
|
||||
{
|
||||
<EXTENSIONS>
|
||||
first = Integer()
|
||||
<TO>
|
||||
(
|
||||
last = Integer()
|
||||
|
|
||||
<MAX>
|
||||
{
|
||||
last=536870911;
|
||||
}
|
||||
)
|
||||
{
|
||||
ExtensionsDescriptor rc = new ExtensionsDescriptor(parent);
|
||||
rc.setFirst(first);
|
||||
rc.setLast(last);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
EnumDescriptor EnumDescriptor(ProtoDescriptor proto, MessageDescriptor parent) :
|
||||
{
|
||||
Token name;
|
||||
LinkedHashMap<String,EnumFieldDescriptor> fields = new LinkedHashMap<String,EnumFieldDescriptor>();
|
||||
EnumDescriptor rc = new EnumDescriptor(proto, parent);
|
||||
LinkedHashMap<String,OptionDescriptor> opts = new LinkedHashMap<String,OptionDescriptor>();
|
||||
|
||||
EnumFieldDescriptor enumD;
|
||||
OptionDescriptor optionD;
|
||||
}
|
||||
{
|
||||
<ENUM> name = <ID> <LBRACE>
|
||||
(
|
||||
LOOKAHEAD(2)
|
||||
<OPTION> optionD = OptionDescriptor() <SEMICOLON>
|
||||
{ opts.put(optionD.getName(),optionD); }
|
||||
|
|
||||
enumD = EnumFieldDescriptor(rc) <SEMICOLON>
|
||||
{ fields.put(enumD.getName(),enumD); }
|
||||
)*
|
||||
<RBRACE>
|
||||
{
|
||||
rc.setName(name.image);
|
||||
rc.setFields(fields);
|
||||
rc.setOptions(opts);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses something like:
|
||||
* optional string foo = 1;
|
||||
*/
|
||||
EnumFieldDescriptor EnumFieldDescriptor(EnumDescriptor parent) :
|
||||
{
|
||||
String name;
|
||||
int value=0;
|
||||
}
|
||||
{
|
||||
|
||||
name = ID()
|
||||
<EQUALS>
|
||||
value = Integer()
|
||||
{
|
||||
EnumFieldDescriptor rc = new EnumFieldDescriptor(parent);
|
||||
rc.setName(name);
|
||||
rc.setValue(value);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
int Integer() :
|
||||
{
|
||||
Token t;
|
||||
}
|
||||
{
|
||||
t = <INTEGER>
|
||||
{
|
||||
return Integer.parseInt(t.image);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
String Rule() :
|
||||
{
|
||||
Token t;
|
||||
}
|
||||
{
|
||||
(
|
||||
t = <REQURIED>
|
||||
|
|
||||
t = <OPTIONAL>
|
||||
|
|
||||
t = <REPEATED>
|
||||
)
|
||||
{
|
||||
return t.image;
|
||||
}
|
||||
}
|
||||
|
||||
String Value() :
|
||||
{
|
||||
Token t;
|
||||
String value=null;
|
||||
}
|
||||
{
|
||||
(
|
||||
value = StringLitteral()
|
||||
|
|
||||
value = ID()
|
||||
|
|
||||
t = <INTEGER>
|
||||
{
|
||||
value = t.image;
|
||||
}
|
||||
|
|
||||
t = <FLOAT>
|
||||
{
|
||||
value = t.image;
|
||||
}
|
||||
)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
String ID() :
|
||||
{
|
||||
Token t;
|
||||
}
|
||||
{
|
||||
(
|
||||
t = <ID>
|
||||
| t = <GROUP>
|
||||
| t = <IMPORT>
|
||||
| t = <PACKAGE>
|
||||
| t = <SERVICE>
|
||||
| t = <RPC>
|
||||
| t = <OPTION>
|
||||
| t = <MESSAGE>
|
||||
| t = <EXTENSIONS>
|
||||
| t = <EXTEND>
|
||||
| t = <ENUM>
|
||||
| t = <REQURIED>
|
||||
| t = <OPTIONAL>
|
||||
| t = <REPEATED>
|
||||
| t = <RETURNS>
|
||||
| t = <TO>
|
||||
| t = <MAX>
|
||||
)
|
||||
{
|
||||
return t.image;
|
||||
}
|
||||
}
|
||||
|
||||
String PackageID() :
|
||||
{
|
||||
String t;
|
||||
StringBuffer sb = new StringBuffer();
|
||||
}
|
||||
{
|
||||
(
|
||||
t = ID()
|
||||
{
|
||||
sb.append(t);
|
||||
}
|
||||
(
|
||||
<PERIOD>
|
||||
t=ID()
|
||||
{
|
||||
sb.append(".");
|
||||
sb.append(t);
|
||||
}
|
||||
)*
|
||||
)
|
||||
{
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
String StringLitteral() :
|
||||
{
|
||||
Token t;
|
||||
}
|
||||
{
|
||||
t = <STRING>
|
||||
{
|
||||
return ParserSupport.decodeString(t);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
=========================================================================
|
||||
== Apache Notice ==
|
||||
=========================================================================
|
||||
|
||||
Apache ActiveMQ
|
||||
Copyright 2005-2008 The Apache Software Foundation
|
||||
|
||||
This product includes software developed by
|
||||
The Apache Software Foundation (http://www.apache.org/).
|
||||
|
||||
=========================================================================
|
||||
== Protocol Buffers Notice ==
|
||||
=========================================================================
|
||||
|
||||
This product includes software developed by the Protocol Buffers
|
||||
project (http://code.google.com/apis/protocolbuffers).
|
||||
|
Loading…
Reference in New Issue