Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
P
protobuf
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
protobuf
Commits
e60ce8bf
Commit
e60ce8bf
authored
Oct 22, 2008
by
Jon Skeet
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Final commit before changing layout
parent
7f90d8ee
Show whitespace changes
Inline
Side-by-side
Showing
39 changed files
with
2161 additions
and
88 deletions
+2161
-88
DependencyResolutionTest.cs
csharp/ProtoGen.Test/DependencyResolutionTest.cs
+80
-1
DescriptorUtilTest.cs
csharp/ProtoGen.Test/DescriptorUtilTest.cs
+69
-0
GeneratorTest.cs
csharp/ProtoGen.Test/GeneratorTest.cs
+6
-2
HelpersTest.cs
csharp/ProtoGen.Test/HelpersTest.cs
+34
-0
ProtoGen.Test.csproj
csharp/ProtoGen.Test/ProtoGen.Test.csproj
+5
-1
DescriptorUtil.cs
csharp/ProtoGen/DescriptorUtil.cs
+108
-0
EnumFieldGenerator.cs
csharp/ProtoGen/EnumFieldGenerator.cs
+75
-0
EnumGenerator.cs
csharp/ProtoGen/EnumGenerator.cs
+19
-0
ExtensionGenerator.cs
csharp/ProtoGen/ExtensionGenerator.cs
+37
-0
FieldGeneratorBase.cs
csharp/ProtoGen/FieldGeneratorBase.cs
+130
-0
Generator.cs
csharp/ProtoGen/Generator.cs
+95
-4
Helpers.cs
csharp/ProtoGen/Helpers.cs
+78
-0
IFieldSourceGenerator.cs
csharp/ProtoGen/IFieldSourceGenerator.cs
+11
-0
ISourceGenerator.cs
csharp/ProtoGen/ISourceGenerator.cs
+5
-0
MessageFieldGenerator.cs
csharp/ProtoGen/MessageFieldGenerator.cs
+92
-0
MessageGenerator.cs
csharp/ProtoGen/MessageGenerator.cs
+453
-0
PrimitiveFieldGenerator.cs
csharp/ProtoGen/PrimitiveFieldGenerator.cs
+70
-0
Program.cs
csharp/ProtoGen/Program.cs
+11
-5
ProtoGen.csproj
csharp/ProtoGen/ProtoGen.csproj
+19
-0
ProtoGen.csproj.user
csharp/ProtoGen/ProtoGen.csproj.user
+7
-0
RepeatedEnumFieldGenerator.cs
csharp/ProtoGen/RepeatedEnumFieldGenerator.cs
+90
-0
RepeatedMessageFieldGenerator.cs
csharp/ProtoGen/RepeatedMessageFieldGenerator.cs
+100
-0
RepeatedPrimitiveFieldGenerator.cs
csharp/ProtoGen/RepeatedPrimitiveFieldGenerator.cs
+84
-0
ServiceGenerator.cs
csharp/ProtoGen/ServiceGenerator.cs
+138
-0
SourceFileGenerator.cs
csharp/ProtoGen/SourceFileGenerator.cs
+29
-0
SourceGeneratorBase.cs
csharp/ProtoGen/SourceGeneratorBase.cs
+50
-0
SourceGenerators.cs
csharp/ProtoGen/SourceGenerators.cs
+42
-0
UmbrellaClassGenerator.cs
csharp/ProtoGen/UmbrellaClassGenerator.cs
+96
-0
UnitTestImportProtoFile.cs
...rotocolBuffers.Test/TestProtos/UnitTestImportProtoFile.cs
+42
-68
CSharpOptions.cs
csharp/ProtocolBuffers/DescriptorProtos/CSharpOptions.cs
+49
-0
DescriptorProtoFile.cs
...p/ProtocolBuffers/DescriptorProtos/DescriptorProtoFile.cs
+0
-0
PartialClasses.cs
csharp/ProtocolBuffers/DescriptorProtos/PartialClasses.cs
+15
-0
FileDescriptor.cs
csharp/ProtocolBuffers/Descriptors/FileDescriptor.cs
+3
-3
RepeatedPrimitiveAccessor.cs
.../ProtocolBuffers/FieldAccess/RepeatedPrimitiveAccessor.cs
+1
-1
SinglePrimitiveAccessor.cs
...rp/ProtocolBuffers/FieldAccess/SinglePrimitiveAccessor.cs
+6
-3
FieldSet.cs
csharp/ProtocolBuffers/FieldSet.cs
+1
-0
ProtocolBuffers.csproj
csharp/ProtocolBuffers/ProtocolBuffers.csproj
+1
-0
TextGenerator.cs
csharp/ProtocolBuffers/TextGenerator.cs
+4
-0
UnknownFieldSet.cs
csharp/ProtocolBuffers/UnknownFieldSet.cs
+6
-0
No files found.
csharp/ProtoGen.Test/DependencyResolutionTest.cs
View file @
e60ce8bf
using
System
;
using
System.Collections.Generic
;
using
System.Text
;
using
Google.ProtocolBuffers.Descriptors
;
using
NUnit.Framework
;
using
Google.ProtocolBuffers.DescriptorProtos
;
using
Google.ProtocolBuffers.ProtoGen
;
namespace
ProtoGen
{
namespace
Google.ProtocolBuffers.
ProtoGen
{
/// <summary>
/// Tests for the dependency resolution in Generator.
/// </summary>
...
...
@@ -12,6 +15,81 @@ namespace ProtoGen {
[
Test
]
public
void
TwoDistinctFiles
()
{
FileDescriptorProto
first
=
new
FileDescriptorProto
.
Builder
{
Name
=
"First"
}.
Build
();
FileDescriptorProto
second
=
new
FileDescriptorProto
.
Builder
{
Name
=
"Second"
}.
Build
();
FileDescriptorSet
set
=
new
FileDescriptorSet
{
FileList
=
{
first
,
second
}
};
IList
<
FileDescriptor
>
converted
=
Generator
.
ConvertDescriptors
(
set
);
Assert
.
AreEqual
(
2
,
converted
.
Count
);
Assert
.
AreEqual
(
"First"
,
converted
[
0
].
Name
);
Assert
.
AreEqual
(
0
,
converted
[
0
].
Dependencies
.
Count
);
Assert
.
AreEqual
(
"Second"
,
converted
[
1
].
Name
);
Assert
.
AreEqual
(
0
,
converted
[
1
].
Dependencies
.
Count
);
}
[
Test
]
public
void
FirstDependsOnSecond
()
{
FileDescriptorProto
first
=
new
FileDescriptorProto
.
Builder
{
Name
=
"First"
,
DependencyList
=
{
"Second"
}
}.
Build
();
FileDescriptorProto
second
=
new
FileDescriptorProto
.
Builder
{
Name
=
"Second"
}.
Build
();
FileDescriptorSet
set
=
new
FileDescriptorSet
{
FileList
=
{
first
,
second
}
};
IList
<
FileDescriptor
>
converted
=
Generator
.
ConvertDescriptors
(
set
);
Assert
.
AreEqual
(
2
,
converted
.
Count
);
Assert
.
AreEqual
(
"First"
,
converted
[
0
].
Name
);
Assert
.
AreEqual
(
1
,
converted
[
0
].
Dependencies
.
Count
);
Assert
.
AreEqual
(
converted
[
1
],
converted
[
0
].
Dependencies
[
0
]);
Assert
.
AreEqual
(
"Second"
,
converted
[
1
].
Name
);
Assert
.
AreEqual
(
0
,
converted
[
1
].
Dependencies
.
Count
);
}
[
Test
]
public
void
SecondDependsOnFirst
()
{
FileDescriptorProto
first
=
new
FileDescriptorProto
.
Builder
{
Name
=
"First"
}.
Build
();
FileDescriptorProto
second
=
new
FileDescriptorProto
.
Builder
{
Name
=
"Second"
,
DependencyList
=
{
"First"
}
}.
Build
();
FileDescriptorSet
set
=
new
FileDescriptorSet
{
FileList
=
{
first
,
second
}
};
IList
<
FileDescriptor
>
converted
=
Generator
.
ConvertDescriptors
(
set
);
Assert
.
AreEqual
(
2
,
converted
.
Count
);
Assert
.
AreEqual
(
"First"
,
converted
[
0
].
Name
);
Assert
.
AreEqual
(
0
,
converted
[
0
].
Dependencies
.
Count
);
Assert
.
AreEqual
(
"Second"
,
converted
[
1
].
Name
);
Assert
.
AreEqual
(
1
,
converted
[
1
].
Dependencies
.
Count
);
Assert
.
AreEqual
(
converted
[
0
],
converted
[
1
].
Dependencies
[
0
]);
}
[
Test
]
public
void
CircularDependency
()
{
FileDescriptorProto
first
=
new
FileDescriptorProto
.
Builder
{
Name
=
"First"
,
DependencyList
=
{
"Second"
}
}.
Build
();
FileDescriptorProto
second
=
new
FileDescriptorProto
.
Builder
{
Name
=
"Second"
,
DependencyList
=
{
"First"
}
}.
Build
();
FileDescriptorSet
set
=
new
FileDescriptorSet
{
FileList
=
{
first
,
second
}
};
try
{
Generator
.
ConvertDescriptors
(
set
);
Assert
.
Fail
(
"Expected exception"
);
}
catch
(
DependencyResolutionException
)
{
// Expected
}
}
[
Test
]
public
void
MissingDependency
()
{
FileDescriptorProto
first
=
new
FileDescriptorProto
.
Builder
{
Name
=
"First"
,
DependencyList
=
{
"Second"
}
}.
Build
();
FileDescriptorSet
set
=
new
FileDescriptorSet
{
FileList
=
{
first
}
};
try
{
Generator
.
ConvertDescriptors
(
set
);
Assert
.
Fail
(
"Expected exception"
);
}
catch
(
DependencyResolutionException
)
{
// Expected
}
}
[
Test
]
public
void
SelfDependency
()
{
FileDescriptorProto
first
=
new
FileDescriptorProto
.
Builder
{
Name
=
"First"
,
DependencyList
=
{
"First"
}
}.
Build
();
FileDescriptorSet
set
=
new
FileDescriptorSet
{
FileList
=
{
first
}
};
try
{
Generator
.
ConvertDescriptors
(
set
);
Assert
.
Fail
(
"Expected exception"
);
}
catch
(
DependencyResolutionException
)
{
// Expected
}
}
}
}
\ No newline at end of file
csharp/ProtoGen.Test/DescriptorUtilTest.cs
0 → 100644
View file @
e60ce8bf
using
Google.ProtocolBuffers.DescriptorProtos
;
using
Google.ProtocolBuffers.Descriptors
;
using
NUnit.Framework
;
namespace
Google.ProtocolBuffers.ProtoGen
{
[
TestFixture
]
public
class
DescriptorUtilTest
{
[
Test
]
public
void
ExplicitNamespace
()
{
FileDescriptorProto
proto
=
new
FileDescriptorProto
.
Builder
{
Name
=
"x"
,
Package
=
"pack"
,
Options
=
new
FileOptions
.
Builder
().
SetExtension
(
CSharpOptions
.
CSharpNamespace
,
"Foo.Bar"
).
Build
()
}.
Build
();
FileDescriptor
descriptor
=
FileDescriptor
.
BuildFrom
(
proto
,
null
);
Assert
.
AreEqual
(
"Foo.Bar"
,
DescriptorUtil
.
GetNamespace
(
descriptor
));
}
[
Test
]
public
void
NoNamespaceFallsBackToPackage
()
{
FileDescriptorProto
proto
=
new
FileDescriptorProto
.
Builder
{
Name
=
"x"
,
Package
=
"pack"
}.
Build
();
FileDescriptor
descriptor
=
FileDescriptor
.
BuildFrom
(
proto
,
null
);
Assert
.
AreEqual
(
"pack"
,
DescriptorUtil
.
GetNamespace
(
descriptor
));
}
[
Test
]
public
void
NoNamespaceOrPackageFallsBackToEmptyString
()
{
FileDescriptorProto
proto
=
new
FileDescriptorProto
.
Builder
{
Name
=
"x"
}.
Build
();
FileDescriptor
descriptor
=
FileDescriptor
.
BuildFrom
(
proto
,
null
);
Assert
.
AreEqual
(
""
,
DescriptorUtil
.
GetNamespace
(
descriptor
));
}
[
Test
]
public
void
ExplicitlyNamedFileClass
()
{
FileDescriptorProto
proto
=
new
FileDescriptorProto
.
Builder
{
Name
=
"x"
,
Options
=
new
FileOptions
.
Builder
().
SetExtension
(
CSharpOptions
.
CSharpUmbrellaClassname
,
"Foo"
).
Build
()
}.
Build
();
FileDescriptor
descriptor
=
FileDescriptor
.
BuildFrom
(
proto
,
null
);
Assert
.
AreEqual
(
"Foo"
,
DescriptorUtil
.
GetUmbrellaClassName
(
descriptor
));
}
[
Test
]
public
void
ImplicitFileClassWithProtoSuffix
()
{
FileDescriptorProto
proto
=
new
FileDescriptorProto
.
Builder
{
Name
=
"foo_bar.proto"
}.
Build
();
FileDescriptor
descriptor
=
FileDescriptor
.
BuildFrom
(
proto
,
null
);
Assert
.
AreEqual
(
"FooBar"
,
DescriptorUtil
.
GetUmbrellaClassName
(
descriptor
));
}
[
Test
]
public
void
ImplicitFileClassWithProtoDevelSuffix
()
{
FileDescriptorProto
proto
=
new
FileDescriptorProto
.
Builder
{
Name
=
"foo_bar.protodevel"
}.
Build
();
FileDescriptor
descriptor
=
FileDescriptor
.
BuildFrom
(
proto
,
null
);
Assert
.
AreEqual
(
"FooBar"
,
DescriptorUtil
.
GetUmbrellaClassName
(
descriptor
));
}
[
Test
]
public
void
ImplicitFileClassWithNoSuffix
()
{
FileDescriptorProto
proto
=
new
FileDescriptorProto
.
Builder
{
Name
=
"foo_bar"
}.
Build
();
FileDescriptor
descriptor
=
FileDescriptor
.
BuildFrom
(
proto
,
null
);
Assert
.
AreEqual
(
"FooBar"
,
DescriptorUtil
.
GetUmbrellaClassName
(
descriptor
));
}
[
Test
]
public
void
ImplicitFileClassWithDirectoryStructure
()
{
FileDescriptorProto
proto
=
new
FileDescriptorProto
.
Builder
{
Name
=
"x/y/foo_bar"
}.
Build
();
FileDescriptor
descriptor
=
FileDescriptor
.
BuildFrom
(
proto
,
null
);
Assert
.
AreEqual
(
"FooBar"
,
DescriptorUtil
.
GetUmbrellaClassName
(
descriptor
));
}
}
}
csharp/ProtoGen.Test/GeneratorTest.cs
View file @
e60ce8bf
using
NUnit.Framework
;
using
Google.ProtocolBuffers.DescriptorProtos
;
using
NUnit.Framework
;
using
Google.ProtocolBuffers.Descriptors
;
namespace
ProtoGen
{
namespace
Google.ProtocolBuffers.
ProtoGen
{
[
TestFixture
]
public
class
GeneratorTest
{
}
}
\ No newline at end of file
csharp/ProtoGen.Test/HelpersTest.cs
0 → 100644
View file @
e60ce8bf
using
Google.ProtocolBuffers.ProtoGen
;
using
NUnit.Framework
;
namespace
Google.ProtocolBuffers.ProtoGen
{
[
TestFixture
]
public
class
HelpersTest
{
[
Test
]
public
void
UnderscoresToPascalCase
()
{
Assert
.
AreEqual
(
"FooBar"
,
Helpers
.
UnderscoresToPascalCase
(
"Foo_bar"
));
Assert
.
AreEqual
(
"FooBar"
,
Helpers
.
UnderscoresToPascalCase
(
"foo_bar"
));
Assert
.
AreEqual
(
"Foo0Bar"
,
Helpers
.
UnderscoresToPascalCase
(
"Foo0bar"
));
Assert
.
AreEqual
(
"FooBar"
,
Helpers
.
UnderscoresToPascalCase
(
"Foo_+_Bar"
));
}
[
Test
]
public
void
UnderscoresToCamelCase
()
{
Assert
.
AreEqual
(
"fooBar"
,
Helpers
.
UnderscoresToCamelCase
(
"Foo_bar"
));
Assert
.
AreEqual
(
"fooBar"
,
Helpers
.
UnderscoresToCamelCase
(
"foo_bar"
));
Assert
.
AreEqual
(
"foo0Bar"
,
Helpers
.
UnderscoresToCamelCase
(
"Foo0bar"
));
Assert
.
AreEqual
(
"fooBar"
,
Helpers
.
UnderscoresToCamelCase
(
"Foo_+_Bar"
));
}
[
Test
]
public
void
StripSuffix
()
{
string
text
=
"FooBar"
;
Assert
.
IsFalse
(
Helpers
.
StripSuffix
(
ref
text
,
"Foo"
));
Assert
.
AreEqual
(
"FooBar"
,
text
);
Assert
.
IsTrue
(
Helpers
.
StripSuffix
(
ref
text
,
"Bar"
));
Assert
.
AreEqual
(
"Foo"
,
text
);
}
}
}
\ No newline at end of file
csharp/ProtoGen.Test/ProtoGen.Test.csproj
View file @
e60ce8bf
...
...
@@ -8,7 +8,7 @@
<ProjectGuid>
{C268DA4C-4004-47DA-AF23-44C983281A68}
</ProjectGuid>
<OutputType>
Library
</OutputType>
<AppDesignerFolder>
Properties
</AppDesignerFolder>
<RootNamespace>
ProtoGen
</RootNamespace>
<RootNamespace>
Google.ProtocolBuffers.
ProtoGen
</RootNamespace>
<AssemblyName>
Google.ProtocolBuffers.ProtoGen.Test
</AssemblyName>
<TargetFrameworkVersion>
v2.0
</TargetFrameworkVersion>
<FileAlignment>
512
</FileAlignment>
...
...
@@ -42,10 +42,14 @@
<HintPath>
..\lib\Rhino.Mocks.dll
</HintPath>
</Reference>
<Reference
Include=
"System"
/>
<Reference
Include=
"System.Data"
/>
<Reference
Include=
"System.Xml"
/>
</ItemGroup>
<ItemGroup>
<Compile
Include=
"DependencyResolutionTest.cs"
/>
<Compile
Include=
"DescriptorUtilTest.cs"
/>
<Compile
Include=
"GeneratorTest.cs"
/>
<Compile
Include=
"HelpersTest.cs"
/>
<Compile
Include=
"Properties\AssemblyInfo.cs"
/>
</ItemGroup>
<ItemGroup>
...
...
csharp/ProtoGen/DescriptorUtil.cs
0 → 100644
View file @
e60ce8bf
using
System
;
using
System.Collections.Generic
;
using
System.Text
;
using
Google.ProtocolBuffers.Descriptors
;
using
Google.ProtocolBuffers.DescriptorProtos
;
namespace
Google.ProtocolBuffers.ProtoGen
{
/// <summary>
/// Utility class for determining namespaces etc.
/// </summary>
internal
static
class
DescriptorUtil
{
internal
static
bool
NestClasses
(
IDescriptor
descriptor
)
{
// Defaults to false
return
descriptor
.
File
.
Options
.
GetExtension
(
CSharpOptions
.
CSharpNestClasses
);
}
internal
static
string
GetNamespace
(
FileDescriptor
descriptor
)
{
if
(
descriptor
.
Name
==
"google/protobuf/descriptor.proto"
)
{
return
typeof
(
DescriptorProtoFile
).
Namespace
;
}
return
descriptor
.
Options
.
HasExtension
(
CSharpOptions
.
CSharpNamespace
)
?
descriptor
.
Options
.
GetExtension
(
CSharpOptions
.
CSharpNamespace
)
:
descriptor
.
Package
;
}
// Groups are hacky: The name of the field is just the lower-cased name
// of the group type. In C#, though, we would like to retain the original
// capitalization of the type name.
internal
static
string
GetFieldName
(
FieldDescriptor
descriptor
)
{
if
(
descriptor
.
FieldType
==
FieldType
.
Group
)
{
return
descriptor
.
MessageType
.
Name
;
}
else
{
return
descriptor
.
Name
;
}
}
internal
static
string
GetClassName
(
IDescriptor
descriptor
)
{
return
ToCSharpName
(
descriptor
.
FullName
,
descriptor
.
File
);
}
internal
static
string
GetFullUmbrellaClassName
(
FileDescriptor
descriptor
)
{
string
result
=
GetNamespace
(
descriptor
);
if
(
result
!=
""
)
result
+=
'.'
;
result
+=
GetUmbrellaClassName
(
descriptor
);
return
"global::"
+
result
;
}
internal
static
string
GetUmbrellaClassName
(
FileDescriptor
descriptor
)
{
if
(
descriptor
.
Name
==
"google/protobuf/descriptor.proto"
)
{
return
typeof
(
DescriptorProtoFile
).
Name
;
}
FileOptions
options
=
descriptor
.
Options
;
if
(
options
.
HasExtension
(
CSharpOptions
.
CSharpUmbrellaClassname
))
{
return
descriptor
.
Options
.
GetExtension
(
CSharpOptions
.
CSharpUmbrellaClassname
);
}
int
lastSlash
=
descriptor
.
Name
.
LastIndexOf
(
'/'
);
string
baseName
=
descriptor
.
Name
.
Substring
(
lastSlash
+
1
);
return
Helpers
.
UnderscoresToPascalCase
(
StripProto
(
baseName
));
}
private
static
string
StripProto
(
string
text
)
{
if
(!
Helpers
.
StripSuffix
(
ref
text
,
".protodevel"
))
{
Helpers
.
StripSuffix
(
ref
text
,
".proto"
);
}
return
text
;
}
private
static
string
ToCSharpName
(
string
name
,
FileDescriptor
file
)
{
string
result
;
if
(!
NestClasses
(
file
))
{
result
=
GetNamespace
(
file
);
}
else
{
result
=
GetUmbrellaClassName
(
file
);
}
if
(
result
!=
""
)
{
result
+=
'.'
;
}
string
classname
;
if
(
file
.
Package
==
""
)
{
classname
=
name
;
}
else
{
// Strip the proto package from full_name since we've replaced it with
// the C# namespace.
classname
=
name
.
Substring
(
file
.
Package
.
Length
+
1
);
}
result
+=
classname
.
Replace
(
"."
,
".Types."
);
return
"global::"
+
result
;
}
internal
static
string
GetMappedTypeName
(
MappedType
type
)
{
switch
(
type
)
{
case
MappedType
.
Int32
:
return
"int"
;
case
MappedType
.
Int64
:
return
"long"
;
case
MappedType
.
UInt32
:
return
"uint"
;
case
MappedType
.
UInt64
:
return
"ulong"
;
case
MappedType
.
Single
:
return
"float"
;
case
MappedType
.
Double
:
return
"double"
;
case
MappedType
.
Boolean
:
return
"bool"
;
case
MappedType
.
String
:
return
"string"
;
case
MappedType
.
ByteString
:
return
"pb::ByteString"
;
case
MappedType
.
Enum
:
return
null
;
case
MappedType
.
Message
:
return
null
;
default
:
throw
new
ArgumentOutOfRangeException
(
"Unknown mapped type "
+
type
);
}
}
}
}
csharp/ProtoGen/EnumFieldGenerator.cs
0 → 100644
View file @
e60ce8bf
using
System
;
using
System.Collections.Generic
;
using
System.Text
;
using
Google.ProtocolBuffers.Descriptors
;
namespace
Google.ProtocolBuffers.ProtoGen
{
internal
class
EnumFieldGenerator
:
FieldGeneratorBase
,
IFieldSourceGenerator
{
internal
EnumFieldGenerator
(
FieldDescriptor
descriptor
)
:
base
(
descriptor
)
{
}
public
void
GenerateMembers
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"private bool has{0};"
,
CapitalizedName
);
writer
.
WriteLine
(
"private {0} {1}_ = {2};"
,
TypeName
,
Name
,
DefaultValue
);
writer
.
WriteLine
(
"public bool Has{0} {{"
,
CapitalizedName
);
writer
.
WriteLine
(
" get {{ return has{0}; }}"
,
CapitalizedName
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public {0} {1} {{"
,
TypeName
,
PropertyName
);
writer
.
WriteLine
(
" get {{ return {0}_; }}"
,
Name
);
writer
.
WriteLine
(
"}"
);
}
public
void
GenerateBuilderMembers
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"public bool Has{0} {{"
,
CapitalizedName
);
writer
.
WriteLine
(
" get {{ return result.Has{0}; }}"
,
CapitalizedName
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public {0} {1} {{"
,
TypeName
,
PropertyName
);
writer
.
WriteLine
(
" get {{ return result.{0}; }}"
,
PropertyName
);
writer
.
WriteLine
(
" set {{ Set{0}(value); }}"
,
CapitalizedName
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public Builder Set{0}({1} value) {{"
,
CapitalizedName
,
TypeName
);
writer
.
WriteLine
(
" result.has{0} = true;"
,
CapitalizedName
);
writer
.
WriteLine
(
" result.{0}_ = value;"
,
Name
);
writer
.
WriteLine
(
" return this;"
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public Builder Clear{0}() {{"
,
CapitalizedName
);
writer
.
WriteLine
(
" result.has{0} = false;"
,
CapitalizedName
);
writer
.
WriteLine
(
" result.{0}_ = {1};"
,
Name
,
DefaultValue
);
writer
.
WriteLine
(
" return this;"
);
writer
.
WriteLine
(
"}"
);
}
public
void
GenerateMergingCode
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"if (other.Has{0}) {{"
,
CapitalizedName
);
writer
.
WriteLine
(
" {0} = other.{0};"
,
PropertyName
);
writer
.
WriteLine
(
"}"
);
}
public
void
GenerateBuildingCode
(
TextGenerator
writer
)
{
// Nothing to do here for enum types
}
public
void
GenerateParsingCode
(
TextGenerator
writer
)
{
// TODO(jonskeet): Make a more efficient way of doing this
writer
.
WriteLine
(
"int rawValue = input.ReadEnum();"
);
writer
.
WriteLine
(
"if (!global::System.Enum.IsDefined(typeof({0}), rawValue)) {{"
,
TypeName
);
writer
.
WriteLine
(
" unknownFields.MergeVarintField({0}, (ulong) rawValue);"
,
Number
);
writer
.
WriteLine
(
"} else {"
);
writer
.
WriteLine
(
" {0} = ({1}) rawValue;"
,
PropertyName
,
TypeName
);
writer
.
WriteLine
(
"}"
);
}
public
void
GenerateSerializationCode
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"if (Has{0}) {{"
,
CapitalizedName
);
writer
.
WriteLine
(
" output.WriteEnum({0}, (int) {1});"
,
Number
,
PropertyName
);
writer
.
WriteLine
(
"}"
);
}
public
void
GenerateSerializedSizeCode
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"if (Has{0}) {{"
,
CapitalizedName
);
writer
.
WriteLine
(
" size += pb::CodedOutputStream.ComputeEnumSize({0}, (int) {1});"
,
Number
,
PropertyName
);
writer
.
WriteLine
(
"}"
);
}
}
}
csharp/ProtoGen/EnumGenerator.cs
0 → 100644
View file @
e60ce8bf
using
Google.ProtocolBuffers.Descriptors
;
namespace
Google.ProtocolBuffers.ProtoGen
{
internal
class
EnumGenerator
:
SourceGeneratorBase
<
EnumDescriptor
>,
ISourceGenerator
{
internal
EnumGenerator
(
EnumDescriptor
descriptor
)
:
base
(
descriptor
)
{
}
public
void
Generate
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"{0} enum {1} {{"
,
ClassAccessLevel
,
Descriptor
.
Name
);
writer
.
Indent
();
foreach
(
EnumValueDescriptor
value
in
Descriptor
.
Values
)
{
writer
.
WriteLine
(
"{0} = {1},"
,
value
.
Name
,
value
.
Number
);
}
writer
.
Outdent
();
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
();
}
}
}
csharp/ProtoGen/ExtensionGenerator.cs
0 → 100644
View file @
e60ce8bf
using
System
;
using
System.Collections.Generic
;
using
System.Text
;
using
Google.ProtocolBuffers.Descriptors
;
namespace
Google.ProtocolBuffers.ProtoGen
{
internal
class
ExtensionGenerator
:
SourceGeneratorBase
<
FieldDescriptor
>,
ISourceGenerator
{
internal
ExtensionGenerator
(
FieldDescriptor
descriptor
)
:
base
(
descriptor
)
{
}
public
void
Generate
(
TextGenerator
writer
)
{
string
name
=
Helpers
.
UnderscoresToPascalCase
(
DescriptorUtil
.
GetFieldName
(
Descriptor
));
string
type
;
switch
(
Descriptor
.
MappedType
)
{
case
MappedType
.
Message
:
type
=
DescriptorUtil
.
GetClassName
(
Descriptor
.
MessageType
);
break
;
case
MappedType
.
Enum
:
type
=
DescriptorUtil
.
GetClassName
(
Descriptor
.
EnumType
);
break
;
default
:
type
=
DescriptorUtil
.
GetMappedTypeName
(
Descriptor
.
MappedType
);
break
;
}
if
(
Descriptor
.
IsRepeated
)
{
writer
.
WriteLine
(
"{0} static readonly"
,
ClassAccessLevel
);
writer
.
WriteLine
(
" pb::GeneratedExtensionBase<scg::IList<{0}>> {1} ="
,
type
,
name
);
writer
.
WriteLine
(
" pb::GeneratedRepeatExtension<{0}>.CreateInstance(Descriptor.Extensions[{1}]);"
,
type
,
Descriptor
.
Index
);
}
else
{
writer
.
WriteLine
(
"{0} static readonly pb::GeneratedExtensionBase<{1}> {2} ="
,
ClassAccessLevel
,
type
,
name
);
writer
.
WriteLine
(
" pb::GeneratedSingleExtension<{0}>.CreateInstance(Descriptor.Extensions[{1}]);"
,
type
,
Descriptor
.
Index
);
}
}
}
}
csharp/ProtoGen/FieldGeneratorBase.cs
0 → 100644
View file @
e60ce8bf
using
System
;
using
Google.ProtocolBuffers.Descriptors
;
using
System.Globalization
;
namespace
Google.ProtocolBuffers.ProtoGen
{
internal
abstract
class
FieldGeneratorBase
:
SourceGeneratorBase
<
FieldDescriptor
>
{
protected
FieldGeneratorBase
(
FieldDescriptor
descriptor
)
:
base
(
descriptor
)
{
}
private
static
bool
AllPrintableAscii
(
string
text
)
{
foreach
(
char
c
in
text
)
{
if
(
c
<
0x20
||
c
>
0x7e
)
{
return
false
;
}
}
return
true
;
}
protected
string
DefaultValue
{
get
{
string
suffix
=
""
;
switch
(
Descriptor
.
FieldType
)
{
case
FieldType
.
Float
:
suffix
=
"F"
;
break
;
case
FieldType
.
Double
:
suffix
=
"D"
;
break
;
case
FieldType
.
Int64
:
suffix
=
"L"
;
break
;
case
FieldType
.
UInt64
:
suffix
=
"UL"
;
break
;
}
switch
(
Descriptor
.
FieldType
)
{
case
FieldType
.
Float
:
case
FieldType
.
Double
:
case
FieldType
.
Int32
:
case
FieldType
.
Int64
:
case
FieldType
.
SInt32
:
case
FieldType
.
SInt64
:
case
FieldType
.
SFixed32
:
case
FieldType
.
SFixed64
:
case
FieldType
.
UInt32
:
case
FieldType
.
UInt64
:
case
FieldType
.
Fixed32
:
case
FieldType
.
Fixed64
:
// The simple Object.ToString converts using the current culture.
// We want to always use the invariant culture so it's predictable.
IConvertible
value
=
(
IConvertible
)
Descriptor
.
DefaultValue
;
return
value
.
ToString
(
CultureInfo
.
InvariantCulture
)
+
suffix
;
case
FieldType
.
Bool
:
return
(
bool
)
Descriptor
.
DefaultValue
?
"true"
:
"false"
;
case
FieldType
.
Bytes
:
if
(!
Descriptor
.
HasDefaultValue
)
{
return
"pb::ByteString.Empty"
;
}
return
string
.
Format
(
"(pb::ByteString) {0}.Descriptor.Fields[{1}].DefaultValue"
,
TypeName
,
Number
);
case
FieldType
.
String
:
if
(
AllPrintableAscii
(
Descriptor
.
Proto
.
DefaultValue
))
{
// All chars are ASCII and printable. In this case we only
// need to escape quotes and backslashes.
return
"\""
+
Descriptor
.
Proto
.
DefaultValue
.
Replace
(
"\\"
,
"\\\\"
)
.
Replace
(
"'"
,
"\\'"
)
.
Replace
(
"\""
,
"\\\""
)
+
"\""
;
}
return
string
.
Format
(
"(string) {0}.Descriptor.Fields[{1}].DefaultValue"
,
TypeName
,
Number
);
case
FieldType
.
Enum
:
return
TypeName
+
"."
+
((
EnumValueDescriptor
)
Descriptor
.
DefaultValue
).
Name
;
case
FieldType
.
Message
:
case
FieldType
.
Group
:
return
TypeName
+
".DefaultInstance"
;
default
:
throw
new
InvalidOperationException
(
"Invalid field descriptor type"
);
}
}
}
/// <summary>
/// Usually the same as CapitalizedName, except when the enclosing type has the same name,
/// in which case an underscore is appended.
/// </summary>
protected
string
PropertyName
{
get
{
string
ret
=
CapitalizedName
;
if
(
ret
==
Descriptor
.
ContainingType
.
Name
)
{
ret
+=
"_"
;
}
return
ret
;
}
}
protected
string
CapitalizedName
{
get
{
return
Helpers
.
UnderscoresToPascalCase
(
DescriptorUtil
.
GetFieldName
(
Descriptor
));
}
}
protected
string
Name
{
get
{
return
Helpers
.
UnderscoresToCamelCase
(
DescriptorUtil
.
GetFieldName
(
Descriptor
));
}
}
protected
int
Number
{
get
{
return
Descriptor
.
FieldNumber
;
}
}
protected
string
TypeName
{
get
{
switch
(
Descriptor
.
FieldType
)
{
case
FieldType
.
Enum
:
return
DescriptorUtil
.
GetClassName
(
Descriptor
.
EnumType
);
case
FieldType
.
Message
:
case
FieldType
.
Group
:
return
DescriptorUtil
.
GetClassName
(
Descriptor
.
MessageType
);
default
:
return
DescriptorUtil
.
GetMappedTypeName
(
Descriptor
.
MappedType
);
}
}
}
protected
string
MessageOrGroup
{
get
{
return
Descriptor
.
FieldType
==
FieldType
.
Group
?
"Group"
:
"Message"
;
}
}
/// <summary>
/// Returns the type name as used in CodedInputStream method names: SFixed32, UInt32 etc.
/// </summary>
protected
string
CapitalizedTypeName
{
get
{
// Our enum names match perfectly. How serendipitous.
return
Descriptor
.
FieldType
.
ToString
();
}
}
}
}
csharp/ProtoGen/Generator.cs
View file @
e60ce8bf
using
System
;
using
System.Collections.Generic
;
using
System.Text
;
using
Google.ProtocolBuffers.DescriptorProtos
;
using
System.IO
;
using
Google.ProtocolBuffers.Descriptors
;
using
Google.ProtocolBuffers.Collections
;
namespace
Google.ProtocolBuffers.ProtoGen
{
/// <summary>
...
...
@@ -27,21 +29,110 @@ namespace Google.ProtocolBuffers.ProtoGen {
public
void
Generate
()
{
foreach
(
string
inputFile
in
options
.
InputFiles
)
{
FileDescriptorSet
descriptorProtos
;
ExtensionRegistry
extensionRegistry
=
ExtensionRegistry
.
CreateInstance
();
extensionRegistry
.
Add
(
CSharpOptions
.
CSharpUmbrellaClassname
);
extensionRegistry
.
Add
(
CSharpOptions
.
CSharpMultipleFiles
);
extensionRegistry
.
Add
(
CSharpOptions
.
CSharpNamespace
);
extensionRegistry
.
Add
(
CSharpOptions
.
CSharpNestClasses
);
extensionRegistry
.
Add
(
CSharpOptions
.
CSharpPublicClasses
);
using
(
Stream
inputStream
=
File
.
OpenRead
(
inputFile
))
{
descriptorProtos
=
FileDescriptorSet
.
ParseFrom
(
inputStream
);
descriptorProtos
=
FileDescriptorSet
.
ParseFrom
(
inputStream
,
extensionRegistry
);
}
IList
<
FileDescriptor
>
descriptors
=
ConvertDescriptors
(
descriptorProtos
);
foreach
(
FileDescriptor
descriptor
in
descriptors
)
{
Generate
(
descriptor
);
}
List
<
FileDescriptor
>
descriptors
=
ConvertDescriptors
(
descriptorProtos
);
}
}
/// <summary>
/// Generates code for a particular file. All dependencies must
/// already have been resolved.
/// </summary>
private
void
Generate
(
FileDescriptor
descriptor
)
{
string
umbrellaClass
=
DescriptorUtil
.
GetUmbrellaClassName
(
descriptor
);
string
ns
=
DescriptorUtil
.
GetNamespace
(
descriptor
);
using
(
TextWriter
textWriter
=
File
.
CreateText
(
Path
.
Combine
(
options
.
OutputDirectory
,
umbrellaClass
+
".cs"
)))
{
TextGenerator
writer
=
new
TextGenerator
(
textWriter
);
UmbrellaClassGenerator
ucg
=
new
UmbrellaClassGenerator
(
descriptor
);
ucg
.
Generate
(
writer
);
/*
GenerateSiblings(umbrellaSource, descriptor, descriptor.MessageTypes);
GenerateSiblings(umbrellaSource, descriptor, descriptor.EnumTypes);
GenerateSiblings(umbrellaSource, descriptor, descriptor.Services);*/
}
}
private
static
void
GenerateSiblings
<
T
>(
SourceFileGenerator
parentSourceGenerator
,
FileDescriptor
file
,
IEnumerable
<
T
>
siblings
)
where
T
:
IDescriptor
{
}
/// <summary>
/// Resolves any dependencies and converts FileDescriptorProtos into FileDescriptors.
/// The list returned is in the same order as the protos are listed in the descriptor set.
/// Note: this method is internal rather than private to allow testing.
/// </summary>
/// <exception cref="DependencyResolutionException">Not all dependencies could be resolved.</exception>
internal
static
List
<
FileDescriptor
>
ConvertDescriptors
(
FileDescriptorSet
descriptorProtos
)
{
return
null
;
internal
static
IList
<
FileDescriptor
>
ConvertDescriptors
(
FileDescriptorSet
descriptorProtos
)
{
// Simple strategy: Keep going through the list of protos to convert, only doing ones where
// we've already converted all the dependencies, until we get to a stalemate
IList
<
FileDescriptorProto
>
fileList
=
descriptorProtos
.
FileList
;
FileDescriptor
[]
converted
=
new
FileDescriptor
[
fileList
.
Count
];
Dictionary
<
string
,
FileDescriptor
>
convertedMap
=
new
Dictionary
<
string
,
FileDescriptor
>();
int
totalConverted
=
0
;
bool
madeProgress
=
true
;
while
(
madeProgress
&&
totalConverted
<
converted
.
Length
)
{
madeProgress
=
false
;
for
(
int
i
=
0
;
i
<
converted
.
Length
;
i
++)
{
if
(
converted
[
i
]
!=
null
)
{
// Already done this one
continue
;
}
FileDescriptorProto
candidate
=
fileList
[
i
];
FileDescriptor
[]
dependencies
=
new
FileDescriptor
[
candidate
.
DependencyList
.
Count
];
bool
foundAllDependencies
=
true
;
for
(
int
j
=
0
;
j
<
dependencies
.
Length
;
j
++)
{
if
(!
convertedMap
.
TryGetValue
(
candidate
.
DependencyList
[
j
],
out
dependencies
[
j
]))
{
foundAllDependencies
=
false
;
break
;
}
}
if
(!
foundAllDependencies
)
{
continue
;
}
madeProgress
=
true
;
totalConverted
++;
converted
[
i
]
=
FileDescriptor
.
BuildFrom
(
candidate
,
dependencies
);
convertedMap
[
candidate
.
Name
]
=
converted
[
i
];
}
}
if
(!
madeProgress
)
{
StringBuilder
remaining
=
new
StringBuilder
();
for
(
int
i
=
0
;
i
<
converted
.
Length
;
i
++)
{
if
(
converted
[
i
]
==
null
)
{
if
(
remaining
.
Length
!=
0
)
{
remaining
.
Append
(
", "
);
}
FileDescriptorProto
failure
=
fileList
[
i
];
remaining
.
Append
(
failure
.
Name
);
remaining
.
Append
(
":"
);
foreach
(
string
dependency
in
failure
.
DependencyList
)
{
if
(!
convertedMap
.
ContainsKey
(
dependency
))
{
remaining
.
Append
(
" "
);
remaining
.
Append
(
dependency
);
}
}
remaining
.
Append
(
";"
);
}
}
throw
new
DependencyResolutionException
(
"Unable to resolve all dependencies: "
+
remaining
);
}
return
Lists
.
AsReadOnly
(
converted
);
}
}
}
csharp/ProtoGen/Helpers.cs
0 → 100644
View file @
e60ce8bf
using
System
;
using
System.Text
;
using
Google.ProtocolBuffers.DescriptorProtos
;
using
Google.ProtocolBuffers.Descriptors
;
namespace
Google.ProtocolBuffers.ProtoGen
{
/// <summary>
/// Helpers to resolve class names etc.
/// </summary>
internal
static
class
Helpers
{
internal
static
string
UnderscoresToPascalCase
(
string
input
)
{
return
UnderscoresToPascalOrCamelCase
(
input
,
true
);
}
internal
static
string
UnderscoresToCamelCase
(
string
input
)
{
return
UnderscoresToPascalOrCamelCase
(
input
,
false
);
}
internal
static
void
WriteNamespaces
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"using pb = global::Google.ProtocolBuffers;"
);
writer
.
WriteLine
(
"using pbc = global::Google.ProtocolBuffers.Collections;"
);
writer
.
WriteLine
(
"using pbd = global::Google.ProtocolBuffers.Descriptors;"
);
writer
.
WriteLine
(
"using scg = global::System.Collections.Generic;"
);
}
/// <summary>
/// Converts a string to Pascal or Camel case. The first letter is capitalized or
/// lower-cased depending on <paramref name="pascal"/> is true.
/// After the first letter, any punctuation is removed but triggers capitalization
/// of the next letter. Digits are preserved but trigger capitalization of the next
/// letter.
/// All capitalisation is done in the invariant culture.
/// </summary>
private
static
string
UnderscoresToPascalOrCamelCase
(
string
input
,
bool
pascal
)
{
StringBuilder
result
=
new
StringBuilder
();
bool
capitaliseNext
=
pascal
;
for
(
int
i
=
0
;
i
<
input
.
Length
;
i
++)
{
char
c
=
input
[
i
];
if
(
'a'
<=
c
&&
c
<=
'z'
)
{
if
(
capitaliseNext
)
{
result
.
Append
(
char
.
ToUpperInvariant
(
c
));
}
else
{
result
.
Append
(
c
);
}
capitaliseNext
=
false
;
}
else
if
(
'A'
<=
c
&&
c
<=
'Z'
)
{
if
(
i
==
0
&&
!
pascal
)
{
// Force first letter to lower-case unless explicitly told to
// capitalize it.
result
.
Append
(
char
.
ToLowerInvariant
(
c
));
}
else
{
// Capital letters after the first are left as-is.
result
.
Append
(
c
);
}
capitaliseNext
=
false
;
}
else
if
(
'0'
<=
c
&&
c
<=
'9'
)
{
result
.
Append
(
c
);
capitaliseNext
=
true
;
}
else
{
capitaliseNext
=
true
;
}
}
return
result
.
ToString
();
}
/// <summary>
/// Attempts to strip a suffix from a string, returning whether
/// or not the suffix was actually present.
/// </summary>
internal
static
bool
StripSuffix
(
ref
string
text
,
string
suffix
)
{
if
(
text
.
EndsWith
(
suffix
))
{
text
=
text
.
Substring
(
0
,
text
.
Length
-
suffix
.
Length
);
return
true
;
}
return
false
;
}
}
}
csharp/ProtoGen/IFieldSourceGenerator.cs
0 → 100644
View file @
e60ce8bf
namespace
Google.ProtocolBuffers.ProtoGen
{
internal
interface
IFieldSourceGenerator
{
void
GenerateMembers
(
TextGenerator
writer
);
void
GenerateBuilderMembers
(
TextGenerator
writer
);
void
GenerateMergingCode
(
TextGenerator
writer
);
void
GenerateBuildingCode
(
TextGenerator
writer
);
void
GenerateParsingCode
(
TextGenerator
writer
);
void
GenerateSerializationCode
(
TextGenerator
writer
);
void
GenerateSerializedSizeCode
(
TextGenerator
writer
);
}
}
csharp/ProtoGen/ISourceGenerator.cs
0 → 100644
View file @
e60ce8bf
namespace
Google.ProtocolBuffers.ProtoGen
{
internal
interface
ISourceGenerator
{
void
Generate
(
TextGenerator
writer
);
}
}
csharp/ProtoGen/MessageFieldGenerator.cs
0 → 100644
View file @
e60ce8bf
using
Google.ProtocolBuffers.Descriptors
;
namespace
Google.ProtocolBuffers.ProtoGen
{
internal
class
MessageFieldGenerator
:
FieldGeneratorBase
,
IFieldSourceGenerator
{
internal
MessageFieldGenerator
(
FieldDescriptor
descriptor
)
:
base
(
descriptor
)
{
}
public
void
GenerateMembers
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"private bool has{0};"
,
CapitalizedName
);
writer
.
WriteLine
(
"private {0} {1}_ = {2};"
,
TypeName
,
Name
,
DefaultValue
);
writer
.
WriteLine
(
"public bool Has{0} {{"
,
CapitalizedName
);
writer
.
WriteLine
(
" get {{ return has{0}; }}"
,
CapitalizedName
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public {0} {1} {{"
,
TypeName
,
CapitalizedName
);
writer
.
WriteLine
(
" get {{ return {0}_; }}"
,
Name
);
writer
.
WriteLine
(
"}"
);
}
public
void
GenerateBuilderMembers
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"public bool Has{0} {{"
,
CapitalizedName
);
writer
.
WriteLine
(
" get {{ return result.Has{0}; }}"
,
CapitalizedName
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public {0} {1} {{"
,
TypeName
,
CapitalizedName
);
writer
.
WriteLine
(
" get {{ return result.{0}; }}"
,
CapitalizedName
);
writer
.
WriteLine
(
" set {{ Set{0}(value); }}"
,
CapitalizedName
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public Builder Set{0}({1} value) {{"
,
CapitalizedName
,
TypeName
);
writer
.
WriteLine
(
" result.has{0} = true;"
,
CapitalizedName
);
writer
.
WriteLine
(
" result.{0}_ = value;"
,
Name
);
writer
.
WriteLine
(
" return this;"
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public Builder Set{0}({1}.Builder builderForValue) {{"
,
CapitalizedName
,
TypeName
);
writer
.
WriteLine
(
" result.has{0} = true;"
,
CapitalizedName
);
writer
.
WriteLine
(
" result.{0}_ = builderForValue.Build();"
,
Name
);
writer
.
WriteLine
(
" return this;"
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public Builder Merge{0}({1} value) {{"
,
CapitalizedName
,
TypeName
);
writer
.
WriteLine
(
" if (result.Has{0} &&"
,
CapitalizedName
);
writer
.
WriteLine
(
" result.{0}_ != {1}) {{"
,
Name
,
DefaultValue
);
writer
.
WriteLine
(
" result.{0}_ = {1}.CreateBuilder(result.{0}_).MergeFrom(value).BuildPartial();"
,
Name
,
TypeName
);
writer
.
WriteLine
(
" } else {"
);
writer
.
WriteLine
(
" result.{0}_ = value;"
,
Name
);
writer
.
WriteLine
(
" }"
);
writer
.
WriteLine
(
" result.has{0} = true;"
,
CapitalizedName
);
writer
.
WriteLine
(
" return this;"
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public Builder Clear{0}() {{"
,
CapitalizedName
);
writer
.
WriteLine
(
" result.has{0} = false;"
,
CapitalizedName
);
writer
.
WriteLine
(
" result.{0}_ = {1};"
,
Name
,
DefaultValue
);
writer
.
WriteLine
(
" return this;"
);
writer
.
WriteLine
(
"}"
);
}
public
void
GenerateMergingCode
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"if (other.Has{0}) {{"
,
CapitalizedName
);
writer
.
WriteLine
(
" Merge{0}(other.{0});"
,
CapitalizedName
);
writer
.
WriteLine
(
"}"
);
}
public
void
GenerateBuildingCode
(
TextGenerator
writer
)
{
// Nothing to do for singular fields
}
public
void
GenerateParsingCode
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"{0}.Builder subBuilder = {0}.CreateBuilder();"
,
TypeName
);
writer
.
WriteLine
(
"if (Has{0}) {{"
,
CapitalizedName
);
writer
.
WriteLine
(
" subBuilder.MergeFrom({0});"
,
CapitalizedName
);
writer
.
WriteLine
(
"}"
);
if
(
Descriptor
.
FieldType
==
FieldType
.
Group
)
{
writer
.
WriteLine
(
"input.ReadGroup({0}, subBuilder, extensionRegistry);"
,
Number
);
}
else
{
writer
.
WriteLine
(
"input.ReadMessage(subBuilder, extensionRegistry);"
);
}
writer
.
WriteLine
(
"{0} = subBuilder.BuildPartial();"
,
CapitalizedName
);
}
public
void
GenerateSerializationCode
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"if (Has{0}) {{"
,
CapitalizedName
);
writer
.
WriteLine
(
" output.Write{0}({1}, {2});"
,
MessageOrGroup
,
Number
,
CapitalizedName
);
writer
.
WriteLine
(
"}"
);
}
public
void
GenerateSerializedSizeCode
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"if (Has{0}) {{"
,
CapitalizedName
);
writer
.
WriteLine
(
" size += pb::CodedOutputStream.Compute{0}Size({1}, {2});"
,
MessageOrGroup
,
Number
,
CapitalizedName
);
writer
.
WriteLine
(
"}"
);
}
}
}
csharp/ProtoGen/MessageGenerator.cs
0 → 100644
View file @
e60ce8bf
using
System.Collections
;
using
Google.ProtocolBuffers.Descriptors
;
using
Google.ProtocolBuffers.DescriptorProtos
;
using
System.Collections.Generic
;
using
ExtensionRange
=
Google
.
ProtocolBuffers
.
DescriptorProtos
.
DescriptorProto
.
Types
.
ExtensionRange
;
namespace
Google.ProtocolBuffers.ProtoGen
{
internal
class
MessageGenerator
:
SourceGeneratorBase
<
MessageDescriptor
>,
ISourceGenerator
{
internal
MessageGenerator
(
MessageDescriptor
descriptor
)
:
base
(
descriptor
)
{
}
private
string
ClassName
{
get
{
return
Descriptor
.
Name
;
}
}
private
string
FullClassName
{
get
{
return
DescriptorUtil
.
GetClassName
(
Descriptor
);
}
}
/// <summary>
/// Get an identifier that uniquely identifies this type within the file.
/// This is used to declare static variables related to this type at the
/// outermost file scope.
/// </summary>
static
string
GetUniqueFileScopeIdentifier
(
IDescriptor
descriptor
)
{
return
"static_"
+
descriptor
.
FullName
.
Replace
(
"."
,
"_"
);
}
internal
void
GenerateStaticVariables
(
TextGenerator
writer
)
{
// Because descriptor.proto (Google.ProtocolBuffers.DescriptorProtos) is
// used in the construction of descriptors, we have a tricky bootstrapping
// problem. To help control static initialization order, we make sure all
// descriptors and other static data that depends on them are members of
// the proto-descriptor class. This way, they will be initialized in
// a deterministic order.
string
identifier
=
GetUniqueFileScopeIdentifier
(
Descriptor
);
// The descriptor for this type.
string
access
=
Descriptor
.
File
.
Options
.
GetExtension
(
CSharpOptions
.
CSharpNestClasses
)
?
"private"
:
"internal"
;
writer
.
WriteLine
(
"{0} static readonly pbd::MessageDescriptor internal__{1}__Descriptor"
,
access
,
identifier
);
if
(
Descriptor
.
ContainingType
==
null
)
{
writer
.
WriteLine
(
" = Descriptor.MessageTypes[{0}];"
,
Descriptor
.
Index
);
}
else
{
writer
.
WriteLine
(
" = internal__{0}__Descriptor.NestedTypes[{1}];"
,
GetUniqueFileScopeIdentifier
(
Descriptor
.
ContainingType
),
Descriptor
.
Index
);
}
writer
.
WriteLine
(
"{0} static pb::FieldAccess.FieldAccessorTable<{1}, {1}.Builder> internal__{2}__FieldAccessorTable"
,
access
,
FullClassName
,
identifier
);
writer
.
WriteLine
(
" = new pb::FieldAccess.FieldAccessorTable<{0}, {0}.Builder>(internal__{1}__Descriptor,"
,
FullClassName
,
identifier
);
writer
.
Print
(
" new string[] { "
);
foreach
(
FieldDescriptor
field
in
Descriptor
.
Fields
)
{
writer
.
Write
(
"\"{0}\", "
,
Helpers
.
UnderscoresToPascalCase
(
DescriptorUtil
.
GetFieldName
(
field
)));
}
writer
.
WriteLine
(
"});"
);
// Generate static members for all nested types.
foreach
(
MessageDescriptor
nestedMessage
in
Descriptor
.
NestedTypes
)
{
new
MessageGenerator
(
nestedMessage
).
GenerateStaticVariables
(
writer
);
}
}
public
void
Generate
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"{0} sealed partial class {1} : pb::{2}Message<{1}, {1}.Builder> {{"
,
ClassAccessLevel
,
ClassName
,
Descriptor
.
Proto
.
ExtensionRangeCount
>
0
?
"Extendable"
:
"Generated"
);
writer
.
Indent
();
// Must call BuildPartial() to make sure all lists are made read-only
writer
.
WriteLine
(
"private static readonly {0} defaultInstance = new Builder().BuildPartial();"
,
ClassName
);
writer
.
WriteLine
(
"public static {0} DefaultInstance {{"
,
ClassName
);
writer
.
WriteLine
(
" get { return defaultInstance; }"
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
();
writer
.
WriteLine
(
"public override {0} DefaultInstanceForType {{"
,
ClassName
);
writer
.
WriteLine
(
" get { return defaultInstance; }"
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
();
writer
.
WriteLine
(
"protected override {0} ThisMessage {{"
,
ClassName
);
writer
.
WriteLine
(
" get { return this; }"
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
();
writer
.
WriteLine
(
"public static pbd::MessageDescriptor Descriptor {"
);
writer
.
WriteLine
(
" get {{ return {0}.internal__{1}__Descriptor; }}"
,
DescriptorUtil
.
GetFullUmbrellaClassName
(
Descriptor
.
File
),
GetUniqueFileScopeIdentifier
(
Descriptor
));
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
();
writer
.
WriteLine
(
"protected override pb::FieldAccess.FieldAccessorTable<{0}, {0}.Builder> InternalFieldAccessors {{"
,
ClassName
);
writer
.
WriteLine
(
" get {{ return {0}.internal__{1}__FieldAccessorTable; }}"
,
DescriptorUtil
.
GetFullUmbrellaClassName
(
Descriptor
.
File
),
GetUniqueFileScopeIdentifier
(
Descriptor
));
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
();
// Extensions don't need to go in an extra nested type
WriteChildren
(
writer
,
null
,
Descriptor
.
Extensions
);
if
(
Descriptor
.
EnumTypes
.
Count
+
Descriptor
.
NestedTypes
.
Count
>
0
)
{
writer
.
WriteLine
(
"#region Nested types"
);
writer
.
WriteLine
(
"public static class Types {"
);
writer
.
Indent
();
WriteChildren
(
writer
,
null
,
Descriptor
.
EnumTypes
);
WriteChildren
(
writer
,
null
,
Descriptor
.
NestedTypes
);
writer
.
Outdent
();
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"#endregion"
);
writer
.
WriteLine
();
}
foreach
(
FieldDescriptor
fieldDescriptor
in
Descriptor
.
Fields
)
{
// Rats: we lose the debug comment here :(
SourceGenerators
.
CreateFieldGenerator
(
fieldDescriptor
).
GenerateMembers
(
writer
);
writer
.
WriteLine
();
}
if
(
Descriptor
.
File
.
Options
.
OptimizeFor
==
FileOptions
.
Types
.
OptimizeMode
.
SPEED
)
{
GenerateIsInitialized
(
writer
);
GenerateMessageSerializationMethods
(
writer
);
}
GenerateParseFromMethods
(
writer
);
GenerateBuilder
(
writer
);
}
private
void
GenerateMessageSerializationMethods
(
TextGenerator
writer
)
{
List
<
FieldDescriptor
>
sortedFields
=
new
List
<
FieldDescriptor
>(
Descriptor
.
Fields
);
sortedFields
.
Sort
((
f1
,
f2
)
=>
f1
.
FieldNumber
.
CompareTo
(
f2
.
FieldNumber
));
List
<
ExtensionRange
>
sortedExtensions
=
new
List
<
ExtensionRange
>(
Descriptor
.
Proto
.
ExtensionRangeList
);
sortedExtensions
.
Sort
((
r1
,
r2
)
=>
(
r1
.
Start
.
CompareTo
(
r2
.
Start
)));
writer
.
WriteLine
(
"public override void WriteTo(pb::CodedOutputStream output) {"
);
writer
.
Indent
();
if
(
Descriptor
.
Proto
.
ExtensionRangeList
.
Count
>
0
)
{
writer
.
WriteLine
(
"pb::ExtendableMessage<{0}, {0}.Builder>.ExtensionWriter extensionWriter = CreateExtensionWriter(this);"
,
ClassName
);
}
// Merge the fields and the extension ranges, both sorted by field number.
for
(
int
i
=
0
,
j
=
0
;
i
<
Descriptor
.
Fields
.
Count
||
j
<
sortedExtensions
.
Count
;
)
{
if
(
i
==
Descriptor
.
Fields
.
Count
)
{
GenerateSerializeOneExtensionRange
(
writer
,
sortedExtensions
[
j
++]);
}
else
if
(
j
==
sortedExtensions
.
Count
)
{
GenerateSerializeOneField
(
writer
,
sortedFields
[
i
++]);
}
else
if
(
sortedFields
[
i
].
FieldNumber
<
sortedExtensions
[
j
].
Start
)
{
GenerateSerializeOneField
(
writer
,
sortedFields
[
i
++]);
}
else
{
GenerateSerializeOneExtensionRange
(
writer
,
sortedExtensions
[
j
++]);
}
}
if
(
Descriptor
.
Proto
.
Options
.
MessageSetWireFormat
)
{
writer
.
WriteLine
(
"UnknownFields.WriteAsMessageSetTo(output);"
);
}
else
{
writer
.
WriteLine
(
"UnknownFields.WriteTo(output);"
);
}
writer
.
Outdent
();
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
();
writer
.
WriteLine
(
"private int memoizedSerializedSize = -1;"
);
writer
.
WriteLine
(
"public override int SerializedSize {"
);
writer
.
Indent
();
writer
.
WriteLine
(
"get {"
);
writer
.
Indent
();
writer
.
WriteLine
(
"int size = memoizedSerializedSize;"
);
writer
.
WriteLine
(
"if (size != -1) return size;"
);
writer
.
WriteLine
();
writer
.
WriteLine
(
"size = 0;"
);
foreach
(
FieldDescriptor
field
in
Descriptor
.
Fields
)
{
SourceGenerators
.
CreateFieldGenerator
(
field
).
GenerateSerializedSizeCode
(
writer
);
}
if
(
Descriptor
.
Proto
.
ExtensionRangeCount
>
0
)
{
writer
.
WriteLine
(
"size += ExtensionsSerializedSize;"
);
}
if
(
Descriptor
.
Options
.
MessageSetWireFormat
)
{
writer
.
WriteLine
(
"size += UnknownFields.SerializedSizeAsMessageSet;"
);
}
else
{
writer
.
WriteLine
(
"size += UnknownFields.SerializedSize;"
);
}
writer
.
WriteLine
(
"memoizedSerializedSize = size;"
);
writer
.
WriteLine
(
"return size;"
);
writer
.
Outdent
();
writer
.
WriteLine
(
"}"
);
writer
.
Outdent
();
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
();
}
private
static
void
GenerateSerializeOneField
(
TextGenerator
writer
,
FieldDescriptor
fieldDescriptor
)
{
SourceGenerators
.
CreateFieldGenerator
(
fieldDescriptor
).
GenerateSerializationCode
(
writer
);
}
private
static
void
GenerateSerializeOneExtensionRange
(
TextGenerator
writer
,
ExtensionRange
extensionRange
)
{
writer
.
WriteLine
(
"extensionWriter.WriteUntil({0}, output);"
,
extensionRange
.
End
);
}
private
void
GenerateParseFromMethods
(
TextGenerator
writer
)
{
// Note: These are separate from GenerateMessageSerializationMethods()
// because they need to be generated even for messages that are optimized
// for code size.
writer
.
WriteLine
(
"public static {0} ParseFrom(pb::ByteString data) {{"
,
ClassName
);
writer
.
WriteLine
(
" return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();"
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public static {0} ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {{"
,
ClassName
);
writer
.
WriteLine
(
" return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();"
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public static {0} ParseFrom(byte[] data) {{"
,
ClassName
);
writer
.
WriteLine
(
" return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();"
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public static {0} ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {{"
,
ClassName
);
writer
.
WriteLine
(
" return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();"
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public static {0} ParseFrom(global::System.IO.Stream input) {{"
,
ClassName
);
writer
.
WriteLine
(
" return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();"
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public static {0} ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {{"
,
ClassName
);
writer
.
WriteLine
(
" return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();"
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public static {0} ParseFrom(pb::CodedInputStream input) {{"
,
ClassName
);
writer
.
WriteLine
(
" return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();"
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public static {0} ParseFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {{"
,
ClassName
);
writer
.
WriteLine
(
" return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();"
);
writer
.
WriteLine
(
"}"
);
}
/// <summary>
/// Returns whether or not the specified message type has any required fields.
/// If it doesn't, calls to check for initialization can be optimised.
/// TODO(jonskeet): Move this into MessageDescriptor?
/// </summary>
private
static
bool
HasRequiredFields
(
MessageDescriptor
descriptor
,
Dictionary
<
MessageDescriptor
,
object
>
alreadySeen
)
{
if
(
alreadySeen
.
ContainsKey
(
descriptor
))
{
// The type is already in cache. This means that either:
// a. The type has no required fields.
// b. We are in the midst of checking if the type has required fields,
// somewhere up the stack. In this case, we know that if the type
// has any required fields, they'll be found when we return to it,
// and the whole call to HasRequiredFields() will return true.
// Therefore, we don't have to check if this type has required fields
// here.
return
false
;
}
alreadySeen
[
descriptor
]
=
descriptor
;
// Value is irrelevant
// If the type has extensions, an extension with message type could contain
// required fields, so we have to be conservative and assume such an
// extension exists.
if
(
descriptor
.
Extensions
.
Count
>
0
)
{
return
true
;
}
foreach
(
FieldDescriptor
field
in
descriptor
.
Fields
)
{
if
(
field
.
IsRequired
)
{
return
true
;
}
// Message or group
if
(
field
.
MappedType
==
MappedType
.
Message
)
{
if
(
HasRequiredFields
(
field
.
MessageType
,
alreadySeen
))
{
return
true
;
}
}
}
return
false
;
}
private
void
GenerateBuilder
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"public static Builder CreateBuilder() { return new Builder(); }"
);
writer
.
WriteLine
(
"public override Builder CreateBuilderForType() { return new Builder(); }"
);
writer
.
WriteLine
(
"public static Builder CreateBuilder({0} prototype) {{"
,
ClassName
);
writer
.
WriteLine
(
" return (Builder) new Builder().MergeFrom(prototype);"
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
();
writer
.
WriteLine
(
"{0} sealed partial class Builder : pb::{2}Builder<{1}, Builder> {{"
,
ClassAccessLevel
,
ClassName
,
Descriptor
.
Proto
.
ExtensionRangeCount
>
0
?
"Extendable"
:
"Generated"
);
writer
.
Indent
();
writer
.
WriteLine
(
"protected override Builder ThisBuilder {"
);
writer
.
WriteLine
(
" get { return this; }"
);
writer
.
WriteLine
(
"}"
);
GenerateCommonBuilderMethods
(
writer
);
if
(
Descriptor
.
File
.
Options
.
OptimizeFor
==
FileOptions
.
Types
.
OptimizeMode
.
SPEED
)
{
GenerateBuilderParsingMethods
(
writer
);
}
foreach
(
FieldDescriptor
field
in
Descriptor
.
Fields
)
{
writer
.
WriteLine
();
// No field comment :(
SourceGenerators
.
CreateFieldGenerator
(
field
).
GenerateBuilderMembers
(
writer
);
}
writer
.
Outdent
();
writer
.
WriteLine
(
"}"
);
writer
.
Outdent
();
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
();
}
private
void
GenerateCommonBuilderMethods
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"{0} Builder() {{}}"
,
ClassAccessLevel
);
writer
.
WriteLine
();
writer
.
WriteLine
(
"{0} result = new {0}();"
,
ClassName
);
writer
.
WriteLine
();
writer
.
WriteLine
(
"protected override {0} MessageBeingBuilt {{"
,
ClassName
);
writer
.
WriteLine
(
" get { return result; }"
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
();
writer
.
WriteLine
(
"public override Builder Clear() {"
);
writer
.
WriteLine
(
" result = new {0}();"
,
ClassName
);
writer
.
WriteLine
(
" return this;"
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
();
writer
.
WriteLine
(
"public override Builder Clone() {"
);
writer
.
WriteLine
(
" return new Builder().MergeFrom(result);"
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
();
writer
.
WriteLine
(
"public override pbd::MessageDescriptor DescriptorForType {"
);
writer
.
WriteLine
(
" get {{ return {0}.Descriptor; }}"
,
ClassName
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
();
writer
.
WriteLine
(
"public override {0} DefaultInstanceForType {{"
,
ClassName
);
writer
.
WriteLine
(
" get {{ return {0}.DefaultInstance; }}"
,
ClassName
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
();
writer
.
WriteLine
(
"public override {0} BuildPartial() {{"
,
ClassName
);
writer
.
Indent
();
foreach
(
FieldDescriptor
field
in
Descriptor
.
Fields
)
{
SourceGenerators
.
CreateFieldGenerator
(
field
).
GenerateBuildingCode
(
writer
);
}
writer
.
WriteLine
(
"{0} returnMe = result;"
,
ClassName
);
writer
.
WriteLine
(
"result = null;"
);
writer
.
WriteLine
(
"return returnMe;"
);
writer
.
Outdent
();
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
();
if
(
Descriptor
.
File
.
Options
.
OptimizeFor
==
FileOptions
.
Types
.
OptimizeMode
.
SPEED
)
{
writer
.
WriteLine
(
"public override Builder MergeFrom(pb::IMessage other) {"
);
writer
.
WriteLine
(
" if (other is {0}) {{"
,
ClassName
);
writer
.
WriteLine
(
" return MergeFrom(({0}) other);"
,
ClassName
);
writer
.
WriteLine
(
" } else {"
);
writer
.
WriteLine
(
" base.MergeFrom(other);"
);
writer
.
WriteLine
(
" return this;"
);
writer
.
WriteLine
(
" }"
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
();
writer
.
WriteLine
(
"public override Builder MergeFrom({0} other) {{"
,
ClassName
);
// Optimization: If other is the default instance, we know none of its
// fields are set so we can skip the merge.
writer
.
Indent
();
writer
.
WriteLine
(
"if (other == {0}.DefaultInstance) return this;"
,
ClassName
);
foreach
(
FieldDescriptor
field
in
Descriptor
.
Fields
)
{
SourceGenerators
.
CreateFieldGenerator
(
field
).
GenerateMergingCode
(
writer
);
}
writer
.
WriteLine
(
"this.MergeUnknownFields(other.UnknownFields);"
);
writer
.
WriteLine
(
"return this;"
);
writer
.
Outdent
();
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
();
}
}
private
void
GenerateBuilderParsingMethods
(
TextGenerator
writer
)
{
List
<
FieldDescriptor
>
sortedFields
=
new
List
<
FieldDescriptor
>(
Descriptor
.
Fields
);
sortedFields
.
Sort
((
f1
,
f2
)
=>
f1
.
FieldNumber
.
CompareTo
(
f2
.
FieldNumber
));
writer
.
WriteLine
(
"public override Builder MergeFrom(pb::CodedInputStream input) {"
);
writer
.
WriteLine
(
" return MergeFrom(input, pb::ExtensionRegistry.Empty);"
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
();
writer
.
WriteLine
(
"public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {"
);
writer
.
Indent
();
writer
.
WriteLine
(
"pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);"
);
writer
.
WriteLine
(
"while (true) {"
);
writer
.
Indent
();
writer
.
WriteLine
(
"uint tag = input.ReadTag();"
);
writer
.
WriteLine
(
"switch (tag) {"
);
writer
.
Indent
();
writer
.
WriteLine
(
"case 0: {"
);
// 0 signals EOF / limit reached
writer
.
WriteLine
(
" this.UnknownFields = unknownFields.Build();"
);
writer
.
WriteLine
(
" return this;"
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"default: {"
);
writer
.
WriteLine
(
" if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) {"
);
writer
.
WriteLine
(
" this.UnknownFields = unknownFields.Build();"
);
writer
.
WriteLine
(
" return this;"
);
// it's an endgroup tag
writer
.
WriteLine
(
" }"
);
writer
.
WriteLine
(
" break;"
);
writer
.
WriteLine
(
"}"
);
foreach
(
FieldDescriptor
field
in
sortedFields
)
{
uint
tag
=
WireFormat
.
MakeTag
(
field
.
FieldNumber
,
WireFormat
.
GetWireType
(
field
.
FieldType
));
writer
.
WriteLine
(
"case {0}: {{"
,
tag
);
writer
.
Indent
();
SourceGenerators
.
CreateFieldGenerator
(
field
).
GenerateParsingCode
(
writer
);
writer
.
WriteLine
(
"break;"
);
writer
.
Outdent
();
writer
.
WriteLine
(
"}"
);
}
writer
.
Outdent
();
writer
.
WriteLine
(
"}"
);
writer
.
Outdent
();
writer
.
WriteLine
(
"}"
);
writer
.
Outdent
();
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
();
}
private
void
GenerateIsInitialized
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"public override bool IsInitialized {"
);
writer
.
Indent
();
writer
.
WriteLine
(
"get {"
);
writer
.
Indent
();
// Check that all required fields in this message are set.
// TODO(kenton): We can optimize this when we switch to putting all the
// "has" fields into a single bitfield.
foreach
(
FieldDescriptor
field
in
Descriptor
.
Fields
)
{
if
(
field
.
IsRequired
)
{
writer
.
WriteLine
(
"if (!has{0}) return false;"
,
Helpers
.
UnderscoresToPascalCase
(
field
.
Name
));
}
}
// Now check that all embedded messages are initialized.
foreach
(
FieldDescriptor
field
in
Descriptor
.
Fields
)
{
if
(
field
.
FieldType
!=
FieldType
.
Message
||
!
HasRequiredFields
(
field
.
MessageType
,
new
Dictionary
<
MessageDescriptor
,
object
>()))
{
continue
;
}
string
propertyName
=
Helpers
.
UnderscoresToPascalCase
(
DescriptorUtil
.
GetFieldName
(
field
));
if
(
field
.
IsRepeated
)
{
writer
.
WriteLine
(
"foreach ({0} element in {1}List) {{"
,
DescriptorUtil
.
GetClassName
(
field
.
MessageType
),
propertyName
);
writer
.
WriteLine
(
" if (!element.IsInitialized) return false;"
);
writer
.
WriteLine
(
"}"
);
}
else
if
(
field
.
IsOptional
)
{
writer
.
WriteLine
(
"if (Has{0}) {{"
,
propertyName
);
writer
.
WriteLine
(
" if (!{0}.IsInitialized) return false;"
,
propertyName
);
writer
.
WriteLine
(
"}"
);
}
else
{
writer
.
WriteLine
(
"if (!{0}.IsInitialized) return false;"
,
propertyName
);
}
}
if
(
Descriptor
.
Extensions
.
Count
>
0
)
{
writer
.
WriteLine
(
"if (!ExtensionsAreInitialized) return false;"
);
}
writer
.
WriteLine
(
"return true;"
);
writer
.
Outdent
();
writer
.
WriteLine
(
"}"
);
writer
.
Outdent
();
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
();
}
}
}
csharp/ProtoGen/PrimitiveFieldGenerator.cs
0 → 100644
View file @
e60ce8bf
using
System
;
using
Google.ProtocolBuffers.Descriptors
;
namespace
Google.ProtocolBuffers.ProtoGen
{
// TODO(jonskeet): Refactor this. There's loads of common code here.
internal
class
PrimitiveFieldGenerator
:
FieldGeneratorBase
,
IFieldSourceGenerator
{
internal
PrimitiveFieldGenerator
(
FieldDescriptor
descriptor
)
:
base
(
descriptor
)
{
}
public
void
GenerateMembers
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"private bool has{0};"
,
CapitalizedName
);
writer
.
WriteLine
(
"private {0} {1}_ = {2};"
,
TypeName
,
Name
,
DefaultValue
);
writer
.
WriteLine
(
"public bool Has{0} {{"
,
CapitalizedName
);
writer
.
WriteLine
(
" get {{ return has{0}; }}"
,
CapitalizedName
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public {0} {1} {{"
,
TypeName
,
PropertyName
);
writer
.
WriteLine
(
" get {{ return {0}_; }}"
,
Name
);
writer
.
WriteLine
(
"}"
);
}
public
void
GenerateBuilderMembers
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"public bool Has{0} {{"
,
CapitalizedName
);
writer
.
WriteLine
(
" get {{ return result.Has{0}; }}"
,
CapitalizedName
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public {0} {1} {{"
,
TypeName
,
PropertyName
);
writer
.
WriteLine
(
" get {{ return result.{0}; }}"
,
PropertyName
);
writer
.
WriteLine
(
" set {{ Set{0}(value); }}"
,
CapitalizedName
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public Builder Set{0}({1} value) {{"
,
CapitalizedName
,
TypeName
);
writer
.
WriteLine
(
" result.has{0} = true;"
,
CapitalizedName
);
writer
.
WriteLine
(
" result.{0}_ = value;"
,
Name
);
writer
.
WriteLine
(
" return this;"
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public Builder Clear{0}() {{"
,
CapitalizedName
);
writer
.
WriteLine
(
" result.has{0} = false;"
,
CapitalizedName
);
writer
.
WriteLine
(
" result.{0}_ = {1};"
,
Name
,
DefaultValue
);
writer
.
WriteLine
(
" return this;"
);
writer
.
WriteLine
(
"}"
);
}
public
void
GenerateMergingCode
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"if (other.Has{0}) {{"
,
CapitalizedName
);
writer
.
WriteLine
(
" {0} = other.{0};"
,
PropertyName
);
writer
.
WriteLine
(
"}"
);
}
public
void
GenerateBuildingCode
(
TextGenerator
writer
)
{
// Nothing to do here for primitive types
}
public
void
GenerateParsingCode
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"{0} = input.Read{1}();"
,
PropertyName
,
CapitalizedTypeName
);
}
public
void
GenerateSerializationCode
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"if (Has{0}) {{"
,
CapitalizedName
);
writer
.
WriteLine
(
" output.Write{0}({1}, {2});"
,
CapitalizedTypeName
,
Number
,
PropertyName
);
writer
.
WriteLine
(
"}"
);
}
public
void
GenerateSerializedSizeCode
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"if (Has{0}) {{"
,
CapitalizedName
);
writer
.
WriteLine
(
" size += pb::CodedOutputStream.Compute{0}Size({1}, {2});"
,
CapitalizedTypeName
,
Number
,
PropertyName
);
writer
.
WriteLine
(
"}"
);
}
}
}
csharp/ProtoGen/Program.cs
View file @
e60ce8bf
using
System
;
using
System.Collections.Generic
;
using
Google.ProtocolBuffers.DescriptorProtos
;
namespace
Google.ProtocolBuffers.ProtoGen
{
/// <summary>
...
...
@@ -8,7 +9,8 @@ namespace Google.ProtocolBuffers.ProtoGen {
class
Program
{
static
int
Main
(
string
[]
args
)
{
try
{
// Hack to make sure everything's initialized
DescriptorProtoFile
.
Descriptor
.
ToString
();
GeneratorOptions
options
=
ParseCommandLineArguments
(
args
);
IList
<
string
>
validationFailures
;
...
...
@@ -25,16 +27,20 @@ namespace Google.ProtocolBuffers.ProtoGen {
return
0
;
}
catch
(
Exception
e
)
{
Console
.
Error
.
WriteLine
(
"Caught unhandled exception: {0}"
,
e
);
Console
.
Error
.
WriteLine
(
"Error: {0}"
,
e
.
Message
);
Console
.
Error
.
WriteLine
();
Console
.
Error
.
WriteLine
(
"Detailed exception information: {0}"
,
e
);
return
1
;
}
}
private
static
GeneratorOptions
ParseCommandLineArguments
(
string
[]
args
)
{
GeneratorOptions
options
=
new
GeneratorOptions
();
string
baseDir
=
"c:\\Users\\Jon\\Documents\\Visual Studio 2008\\Projects\\ProtocolBuffers"
;
options
.
OutputDirectory
=
baseDir
+
"\\tmp"
;
options
.
InputFiles
=
new
[]
{
baseDir
+
"\\protos\\nwind.protobin"
};
//string baseDir = "c:\\Users\\Jon\\Documents\\Visual Studio 2008\\Projects\\ProtocolBuffers";
//options.OutputDirectory = baseDir + "\\tmp";
//options.InputFiles = new[] { baseDir + "\\protos\\nwind-solo.protobin" };
options
.
OutputDirectory
=
"."
;
options
.
InputFiles
=
args
;
return
options
;
}
}
...
...
csharp/ProtoGen/ProtoGen.csproj
View file @
e60ce8bf
...
...
@@ -38,12 +38,31 @@
<Reference
Include=
"System"
/>
</ItemGroup>
<ItemGroup>
<Compile
Include=
"DescriptorUtil.cs"
/>
<Compile
Include=
"EnumFieldGenerator.cs"
/>
<Compile
Include=
"EnumGenerator.cs"
/>
<Compile
Include=
"ExtensionGenerator.cs"
/>
<Compile
Include=
"FieldGeneratorBase.cs"
/>
<Compile
Include=
"IFieldSourceGenerator.cs"
/>
<Compile
Include=
"ISourceGenerator.cs"
/>
<Compile
Include=
"MessageFieldGenerator.cs"
/>
<Compile
Include=
"MessageGenerator.cs"
/>
<Compile
Include=
"PrimitiveFieldGenerator.cs"
/>
<Compile
Include=
"RepeatedEnumFieldGenerator.cs"
/>
<Compile
Include=
"RepeatedMessageFieldGenerator.cs"
/>
<Compile
Include=
"RepeatedPrimitiveFieldGenerator.cs"
/>
<Compile
Include=
"ServiceGenerator.cs"
/>
<Compile
Include=
"SourceFileGenerator.cs"
/>
<Compile
Include=
"DependencyResolutionException.cs"
/>
<Compile
Include=
"Generator.cs"
/>
<Compile
Include=
"GeneratorOptions.cs"
/>
<Compile
Include=
"Helpers.cs"
/>
<Compile
Include=
"InvalidOptionsException.cs"
/>
<Compile
Include=
"Program.cs"
/>
<Compile
Include=
"Properties\AssemblyInfo.cs"
/>
<Compile
Include=
"SourceGeneratorBase.cs"
/>
<Compile
Include=
"SourceGenerators.cs"
/>
<Compile
Include=
"UmbrellaClassGenerator.cs"
/>
</ItemGroup>
<ItemGroup>
<None
Include=
"app.config"
/>
...
...
csharp/ProtoGen/ProtoGen.csproj.user
0 → 100644
View file @
e60ce8bf
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<StartWorkingDirectory>c:\Users\Jon\Documents\Visual Studio 2008\Projects\ProtocolBuffers\csharp\testprotos</StartWorkingDirectory>
<StartArguments>unittest.protobin</StartArguments>
</PropertyGroup>
</Project>
\ No newline at end of file
csharp/ProtoGen/RepeatedEnumFieldGenerator.cs
0 → 100644
View file @
e60ce8bf
using
System
;
using
System.Collections.Generic
;
using
System.Text
;
using
Google.ProtocolBuffers.Descriptors
;
namespace
Google.ProtocolBuffers.ProtoGen
{
internal
class
RepeatedEnumFieldGenerator
:
FieldGeneratorBase
,
IFieldSourceGenerator
{
internal
RepeatedEnumFieldGenerator
(
FieldDescriptor
descriptor
)
:
base
(
descriptor
)
{
}
public
void
GenerateMembers
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"private pbc::PopsicleList<{0}> {1}_ = new pbc::PopsicleList<{0}>();"
,
TypeName
,
Name
);
writer
.
WriteLine
(
"public scg::IList<{0}> {1}List {{"
,
TypeName
,
CapitalizedName
);
writer
.
WriteLine
(
" get {{ return pbc::Lists.AsReadOnly({0}_); }}"
,
Name
);
writer
.
WriteLine
(
"}"
);
// TODO(jonskeet): Redundant API calls? Possibly - include for portability though. Maybe create an option.
writer
.
WriteLine
(
"public int {0}Count {{"
,
CapitalizedName
);
writer
.
WriteLine
(
" get {{ return {0}_.Count; }}"
,
Name
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public {0} Get{1}(int index) {{"
,
TypeName
,
CapitalizedName
);
writer
.
WriteLine
(
" return {0}_[index];"
,
Name
);
writer
.
WriteLine
(
"}"
);
}
public
void
GenerateBuilderMembers
(
TextGenerator
writer
)
{
// Note: We can return the original list here, because we make it unmodifiable when we build
writer
.
WriteLine
(
"public scg::IList<{0}> {1}List {{"
,
TypeName
,
CapitalizedName
);
writer
.
WriteLine
(
" get {{ return result.{0}_; }}"
,
Name
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public int {0}Count {{"
,
CapitalizedName
);
writer
.
WriteLine
(
" get {{ return result.{0}Count; }}"
,
CapitalizedName
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public {0} Get{1}(int index) {{"
,
TypeName
,
CapitalizedName
);
writer
.
WriteLine
(
" return result.Get{0}(index);"
,
CapitalizedName
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public Builder Set{0}(int index, {1} value) {{"
,
CapitalizedName
,
TypeName
);
writer
.
WriteLine
(
" result.{0}_[index] = value;"
,
Name
);
writer
.
WriteLine
(
" return this;"
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public Builder Add{0}({1} value) {{"
,
CapitalizedName
,
TypeName
);
writer
.
WriteLine
(
" result.{0}_.Add(value);"
,
Name
,
TypeName
);
writer
.
WriteLine
(
" return this;"
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public Builder AddRange{0}(scg::IEnumerable<{1}> values) {{"
,
CapitalizedName
,
TypeName
);
writer
.
WriteLine
(
" base.AddRange(values, result.{0}_);"
,
Name
);
writer
.
WriteLine
(
" return this;"
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public Builder Clear{0}() {{"
,
CapitalizedName
);
writer
.
WriteLine
(
" result.{0}_.Clear();"
,
Name
);
writer
.
WriteLine
(
" return this;"
);
writer
.
WriteLine
(
"}"
);
}
public
void
GenerateMergingCode
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"if (other.{0}_.Count != 0) {{"
,
Name
);
writer
.
WriteLine
(
" base.AddRange(other.{0}_, result.{0}_);"
,
Name
);
writer
.
WriteLine
(
"}"
);
}
public
void
GenerateBuildingCode
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"result.{0}_.MakeReadOnly();"
,
Name
);
}
public
void
GenerateParsingCode
(
TextGenerator
writer
)
{
// TODO(jonskeet): Make a more efficient way of doing this
writer
.
WriteLine
(
"int rawValue = input.ReadEnum();"
);
writer
.
WriteLine
(
"if (!global::System.Enum.IsDefined(typeof({0}), rawValue)) {{"
,
TypeName
);
writer
.
WriteLine
(
" unknownFields.MergeVarintField({0}, (ulong) rawValue);"
,
Number
);
writer
.
WriteLine
(
"} else {"
);
writer
.
WriteLine
(
" Add{0}({1} rawValue);"
,
CapitalizedName
,
TypeName
);
writer
.
WriteLine
(
"}"
);
}
public
void
GenerateSerializationCode
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"foreach ({0} element in {1}List) {{"
,
TypeName
,
CapitalizedName
);
writer
.
WriteLine
(
" output.WriteEnum({0}, (int) element);"
,
Number
);
writer
.
WriteLine
(
"}"
);
}
public
void
GenerateSerializedSizeCode
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"foreach ({0} element in {1}List) {{"
,
TypeName
,
CapitalizedName
);
writer
.
WriteLine
(
" size += pb::CodedOutputStream.ComputeEnumSize({0}, (int) element);"
,
Number
);
writer
.
WriteLine
(
"}"
);
}
}
}
csharp/ProtoGen/RepeatedMessageFieldGenerator.cs
0 → 100644
View file @
e60ce8bf
using
System
;
using
System.Collections.Generic
;
using
System.Text
;
using
Google.ProtocolBuffers.Descriptors
;
namespace
Google.ProtocolBuffers.ProtoGen
{
internal
class
RepeatedMessageFieldGenerator
:
FieldGeneratorBase
,
IFieldSourceGenerator
{
internal
RepeatedMessageFieldGenerator
(
FieldDescriptor
descriptor
)
:
base
(
descriptor
)
{
}
public
void
GenerateMembers
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"private pbc::PopsicleList<{0}> {1}_ = new pbc::PopsicleList<{0}>();"
,
TypeName
,
Name
);
writer
.
WriteLine
(
"public scg::IList<{0}> {1}List {{"
,
TypeName
,
CapitalizedName
);
writer
.
WriteLine
(
" get {{ return {0}_; }}"
,
Name
);
writer
.
WriteLine
(
"}"
);
// TODO(jonskeet): Redundant API calls? Possibly - include for portability though. Maybe create an option.
writer
.
WriteLine
(
"public int {0}Count {{"
,
CapitalizedName
);
writer
.
WriteLine
(
" get {{ return {0}_.Count; }}"
,
Name
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public {0} Get{1}(int index) {{"
,
TypeName
,
CapitalizedName
);
writer
.
WriteLine
(
" return {0}_[index];"
,
Name
);
writer
.
WriteLine
(
"}"
);
}
public
void
GenerateBuilderMembers
(
TextGenerator
writer
)
{
// Note: We can return the original list here, because we make it unmodifiable when we build
writer
.
WriteLine
(
"public scg::IList<{0}> {1}List {{"
,
TypeName
,
CapitalizedName
);
writer
.
WriteLine
(
" get {{ return result.{0}_; }}"
,
Name
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public int {0}Count {{"
,
CapitalizedName
);
writer
.
WriteLine
(
" get {{ return result.{0}Count; }}"
,
CapitalizedName
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public {0} Get{1}(int index) {{"
,
TypeName
,
CapitalizedName
);
writer
.
WriteLine
(
" return result.Get{0}(index);"
,
CapitalizedName
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public Builder Set{0}(int index, {1} value) {{"
,
CapitalizedName
,
TypeName
);
writer
.
WriteLine
(
" result.{0}_[index] = value;"
,
Name
);
writer
.
WriteLine
(
" return this;"
);
writer
.
WriteLine
(
"}"
);
// Extra overload for builder (just on messages)
writer
.
WriteLine
(
"public Builder Set{0}(int index, {1}.Builder builderForValue) {{"
,
CapitalizedName
,
TypeName
);
writer
.
WriteLine
(
" result.{0}_[index] = builderForValue.Build();"
,
Name
);
writer
.
WriteLine
(
" return this;"
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public Builder Add{0}({1} value) {{"
,
CapitalizedName
,
TypeName
);
writer
.
WriteLine
(
" result.{0}_.Add(value);"
,
Name
,
TypeName
);
writer
.
WriteLine
(
" return this;"
);
writer
.
WriteLine
(
"}"
);
// Extra overload for builder (just on messages)
writer
.
WriteLine
(
"public Builder Add{0}({1}.Builder builderForValue) {{"
,
CapitalizedName
,
TypeName
);
writer
.
WriteLine
(
" result.{0}_.Add(builderForValue.Build());"
,
Name
);
writer
.
WriteLine
(
" return this;"
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public Builder AddRange{0}(scg::IEnumerable<{1}> values) {{"
,
CapitalizedName
,
TypeName
);
writer
.
WriteLine
(
" base.AddRange(values, result.{0}_);"
,
Name
);
writer
.
WriteLine
(
" return this;"
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public Builder Clear{0}() {{"
,
CapitalizedName
);
writer
.
WriteLine
(
" result.{0}_.Clear();"
,
Name
);
writer
.
WriteLine
(
" return this;"
);
writer
.
WriteLine
(
"}"
);
}
public
void
GenerateMergingCode
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"if (other.{0}_.Count != 0) {{"
,
Name
);
writer
.
WriteLine
(
" base.AddRange(other.{0}_, result.{0}_);"
,
Name
);
writer
.
WriteLine
(
"}"
);
}
public
void
GenerateBuildingCode
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"result.{0}_.MakeReadOnly();"
,
Name
);
}
public
void
GenerateParsingCode
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"{0}.Builder subBuilder = {0}.CreateBuilder();"
,
TypeName
);
if
(
Descriptor
.
FieldType
==
FieldType
.
Group
)
{
writer
.
WriteLine
(
"input.ReadGroup({0}, subBuilder, extensionRegistry);"
,
Number
);
}
else
{
writer
.
WriteLine
(
"input.ReadMessage(subBuilder, extensionRegistry);"
);
}
writer
.
WriteLine
(
"Add{0}(subBuilder.BuildPartial());"
,
CapitalizedName
);
}
public
void
GenerateSerializationCode
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"foreach ({0} element in {1}List) {{"
,
TypeName
,
CapitalizedName
);
writer
.
WriteLine
(
" output.Write{0}({1}, element);"
,
MessageOrGroup
,
Number
);
writer
.
WriteLine
(
"}"
);
}
public
void
GenerateSerializedSizeCode
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"foreach ({0} element in {1}List) {{"
,
TypeName
,
CapitalizedName
);
writer
.
WriteLine
(
" size += pb::CodedOutputStream.Compute{0}Size({1}, element);"
,
MessageOrGroup
,
Number
);
writer
.
WriteLine
(
"}"
);
}
}
}
csharp/ProtoGen/RepeatedPrimitiveFieldGenerator.cs
0 → 100644
View file @
e60ce8bf
using
System
;
using
System.Collections.Generic
;
using
System.Text
;
using
Google.ProtocolBuffers.Descriptors
;
namespace
Google.ProtocolBuffers.ProtoGen
{
internal
class
RepeatedPrimitiveFieldGenerator
:
FieldGeneratorBase
,
IFieldSourceGenerator
{
internal
RepeatedPrimitiveFieldGenerator
(
FieldDescriptor
descriptor
)
:
base
(
descriptor
)
{
}
public
void
GenerateMembers
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"private pbc::PopsicleList<{0}> {1}_ = new pbc::PopsicleList<{0}>();"
,
TypeName
,
Name
);
writer
.
WriteLine
(
"public scg::IList<{0}> {1}List {{"
,
TypeName
,
CapitalizedName
);
writer
.
WriteLine
(
" get {{ return pbc::Lists.AsReadOnly({0}_); }}"
,
Name
);
writer
.
WriteLine
(
"}"
);
// TODO(jonskeet): Redundant API calls? Possibly - include for portability though. Maybe create an option.
writer
.
WriteLine
(
"public int {0}Count {{"
,
CapitalizedName
);
writer
.
WriteLine
(
" get {{ return {0}_.Count; }}"
,
Name
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public {0} Get{1}(int index) {{"
,
TypeName
,
CapitalizedName
);
writer
.
WriteLine
(
" return {0}_[index];"
,
Name
);
writer
.
WriteLine
(
"}"
);
}
public
void
GenerateBuilderMembers
(
TextGenerator
writer
)
{
// Note: We can return the original list here, because we make it unmodifiable when we build
writer
.
WriteLine
(
"public scg::IList<{0}> {1}List {{"
,
TypeName
,
CapitalizedName
);
writer
.
WriteLine
(
" get {{ return result.{0}_; }}"
,
Name
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public int {0}Count {{"
,
CapitalizedName
);
writer
.
WriteLine
(
" get {{ return result.{0}Count; }}"
,
CapitalizedName
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public {0} Get{1}(int index) {{"
,
TypeName
,
CapitalizedName
);
writer
.
WriteLine
(
" return result.Get{0}(index);"
,
CapitalizedName
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public Builder Set{0}(int index, {1} value) {{"
,
CapitalizedName
,
TypeName
);
writer
.
WriteLine
(
" result.{0}_[index] = value;"
,
Name
);
writer
.
WriteLine
(
" return this;"
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public Builder Add{0}({1} value) {{"
,
CapitalizedName
,
TypeName
);
writer
.
WriteLine
(
" result.{0}_.Add(value);"
,
Name
,
TypeName
);
writer
.
WriteLine
(
" return this;"
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public Builder AddRange{0}(scg::IEnumerable<{1}> values) {{"
,
CapitalizedName
,
TypeName
);
writer
.
WriteLine
(
" base.AddRange(values, result.{0}_);"
,
Name
);
writer
.
WriteLine
(
" return this;"
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"public Builder Clear{0}() {{"
,
CapitalizedName
);
writer
.
WriteLine
(
" result.{0}_.Clear();"
,
Name
);
writer
.
WriteLine
(
" return this;"
);
writer
.
WriteLine
(
"}"
);
}
public
void
GenerateMergingCode
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"if (other.{0}_.Count != 0) {{"
,
Name
);
writer
.
WriteLine
(
" base.AddRange(other.{0}_, result.{0}_);"
,
Name
);
writer
.
WriteLine
(
"}"
);
}
public
void
GenerateBuildingCode
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"result.{0}_.MakeReadOnly();"
,
Name
);
}
public
void
GenerateParsingCode
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"Add{0}(input.Read{1}());"
,
CapitalizedName
,
CapitalizedTypeName
);
}
public
void
GenerateSerializationCode
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"foreach ({0} element in {1}List) {{"
,
TypeName
,
CapitalizedName
);
writer
.
WriteLine
(
" output.Write{0}({1}, element);"
,
CapitalizedTypeName
,
Number
);
writer
.
WriteLine
(
"}"
);
}
public
void
GenerateSerializedSizeCode
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"foreach ({0} element in {1}List) {{"
,
TypeName
,
CapitalizedName
);
writer
.
WriteLine
(
" size += pb::CodedOutputStream.Compute{0}Size({1}, element);"
,
CapitalizedTypeName
,
Number
);
writer
.
WriteLine
(
"}"
);
}
}
}
csharp/ProtoGen/ServiceGenerator.cs
0 → 100644
View file @
e60ce8bf
using
System
;
using
System.Collections.Generic
;
using
System.Text
;
using
Google.ProtocolBuffers.Descriptors
;
namespace
Google.ProtocolBuffers.ProtoGen
{
internal
class
ServiceGenerator
:
SourceGeneratorBase
<
ServiceDescriptor
>,
ISourceGenerator
{
private
enum
RequestOrResponse
{
Request
,
Response
}
internal
ServiceGenerator
(
ServiceDescriptor
descriptor
)
:
base
(
descriptor
)
{
}
public
void
Generate
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"{0} abstract class {1} : pb::IService {{"
,
ClassAccessLevel
,
Descriptor
.
Name
);
writer
.
Indent
();
foreach
(
MethodDescriptor
method
in
Descriptor
.
Methods
)
{
writer
.
WriteLine
(
"{0} abstract void {1}("
,
ClassAccessLevel
,
Helpers
.
UnderscoresToPascalCase
(
method
.
Name
));
writer
.
WriteLine
(
" pb::IRpcController controller,"
);
writer
.
WriteLine
(
" {0} request,"
,
DescriptorUtil
.
GetClassName
(
method
.
InputType
));
writer
.
WriteLine
(
" global::System.Action<{0}> done);"
,
DescriptorUtil
.
GetClassName
(
method
.
OutputType
));
}
// Generate Descriptor and DescriptorForType.
writer
.
WriteLine
();
writer
.
WriteLine
(
"{0} static pbd::ServiceDescriptor Descriptor {{"
,
ClassAccessLevel
);
writer
.
WriteLine
(
" get {{ return {0}.Descriptor.Services[{1}]; }}"
,
DescriptorUtil
.
GetUmbrellaClassName
(
Descriptor
.
File
),
Descriptor
.
Index
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"{0} pbd::ServiceDescriptor DescriptorForType {{"
,
ClassAccessLevel
);
writer
.
WriteLine
(
" get { return Descriptor; }"
);
writer
.
WriteLine
(
"}"
);
GenerateCallMethod
(
writer
);
GenerateGetPrototype
(
RequestOrResponse
.
Request
,
writer
);
GenerateGetPrototype
(
RequestOrResponse
.
Response
,
writer
);
GenerateStub
(
writer
);
writer
.
Outdent
();
writer
.
WriteLine
(
"}"
);
}
private
void
GenerateCallMethod
(
TextGenerator
writer
)
{
writer
.
WriteLine
();
writer
.
WriteLine
(
"public void CallMethod("
,
ClassAccessLevel
);
writer
.
WriteLine
(
" pbd::MethodDescriptor method,"
);
writer
.
WriteLine
(
" pb::IRpcController controller,"
);
writer
.
WriteLine
(
" pb::IMessage request,"
);
writer
.
WriteLine
(
" global::System.Action<pb::IMessage> done) {"
);
writer
.
Indent
();
writer
.
WriteLine
(
"if (method.Service != Descriptor) {"
);
writer
.
WriteLine
(
" throw new global::System.ArgumentException("
);
writer
.
WriteLine
(
" \"Service.CallMethod() given method descriptor for wrong service type.\");"
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"switch(method.Index) {"
);
writer
.
Indent
();
foreach
(
MethodDescriptor
method
in
Descriptor
.
Methods
)
{
writer
.
WriteLine
(
"case {0}:"
,
method
.
Index
);
writer
.
WriteLine
(
" this.{0}(controller, ({0}) request,"
,
Helpers
.
UnderscoresToPascalCase
(
method
.
Name
),
DescriptorUtil
.
GetClassName
(
method
.
InputType
));
writer
.
WriteLine
(
" pb::RpcUtil.SpecializeCallback<{0}>("
,
DescriptorUtil
.
GetClassName
(
method
.
OutputType
));
writer
.
WriteLine
(
" done));"
);
writer
.
WriteLine
(
" return;"
);
}
writer
.
WriteLine
(
"default:"
);
writer
.
WriteLine
(
" throw new global::System.InvalidOperationException(\"Can't get here.\");"
);
writer
.
Outdent
();
writer
.
WriteLine
(
"}"
);
writer
.
Outdent
();
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
();
}
private
void
GenerateGetPrototype
(
RequestOrResponse
which
,
TextGenerator
writer
)
{
writer
.
WriteLine
(
"public pb::IMessage Get{0}Prototype(pbd::MethodDescriptor method) {{"
,
which
);
writer
.
Indent
();
writer
.
WriteLine
(
"if (method.Service != Descriptor) {"
);
writer
.
WriteLine
(
" throw new global::System.ArgumentException("
);
writer
.
WriteLine
(
" \"Service.Get{0}Prototype() given method descriptor for wrong service type.\");"
,
which
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"switch(method.Index) {"
);
writer
.
Indent
();
foreach
(
MethodDescriptor
method
in
Descriptor
.
Methods
)
{
writer
.
WriteLine
(
"case {0}:"
,
method
.
Index
);
writer
.
WriteLine
(
" return {0}.DefaultInstance;"
,
DescriptorUtil
.
GetClassName
(
which
==
RequestOrResponse
.
Request
?
method
.
InputType
:
method
.
OutputType
));
}
writer
.
WriteLine
(
"default:"
);
writer
.
WriteLine
(
" throw new global::System.InvalidOperationException(\"Can't get here.\");"
);
writer
.
Outdent
();
writer
.
WriteLine
(
"}"
);
writer
.
Outdent
();
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
();
}
private
void
GenerateStub
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"public static Stub CreateStub(pb::IRpcChannel channel) {"
);
writer
.
WriteLine
(
" return new Stub(channel);"
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
();
writer
.
WriteLine
(
"{0} class Stub : {1} {{"
,
ClassAccessLevel
,
DescriptorUtil
.
GetClassName
(
Descriptor
));
writer
.
Indent
();
writer
.
WriteLine
(
"internal Stub(pb::IRpcChannel channel) {"
);
writer
.
WriteLine
(
" this.channel = channel;"
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
();
writer
.
WriteLine
(
"private readonly pb::IRpcChannel channel;"
);
writer
.
WriteLine
();
writer
.
WriteLine
(
"public pb::IRpcChannel Channel {"
);
writer
.
WriteLine
(
" get { return channel; }"
);
writer
.
WriteLine
(
"}"
);
foreach
(
MethodDescriptor
method
in
Descriptor
.
Methods
)
{
writer
.
WriteLine
();
writer
.
WriteLine
(
"public override void {0}("
,
Helpers
.
UnderscoresToPascalCase
(
method
.
Name
));
writer
.
WriteLine
(
" pb::IRpcController controller,"
);
writer
.
WriteLine
(
" {0} request,"
,
DescriptorUtil
.
GetClassName
(
method
.
InputType
));
writer
.
WriteLine
(
" global::System.Action<{0}> done) {{"
,
DescriptorUtil
.
GetClassName
(
method
.
OutputType
));
writer
.
Indent
();
writer
.
WriteLine
(
"channel.CallMethod(Descriptor.Methods[{0}],"
,
method
.
Index
);
writer
.
WriteLine
(
" controller, request, {0}.DefaultInstance,"
,
DescriptorUtil
.
GetClassName
(
method
.
OutputType
));
writer
.
WriteLine
(
" pb::RpcUtil.GeneralizeCallback<{0}, {0}.Builder>(done, {0}.DefaultInstance));"
,
DescriptorUtil
.
GetClassName
(
method
.
OutputType
));
writer
.
Outdent
();
writer
.
WriteLine
(
"}"
);
}
writer
.
Outdent
();
writer
.
WriteLine
(
"}"
);
}
}
}
csharp/ProtoGen/SourceFileGenerator.cs
0 → 100644
View file @
e60ce8bf
using
System
;
using
System.Collections.Generic
;
using
System.IO
;
using
System.Text
;
using
Google.ProtocolBuffers.Descriptors
;
namespace
Google.ProtocolBuffers.ProtoGen
{
/// <summary>
/// Generator to hold a TextGenerator, generate namespace aliases etc.
/// Each source file created uses one of these, and it can be used to create
/// multiple classes within the same file.
/// </summary>
internal
class
SourceFileGenerator
{
private
readonly
TextGenerator
output
;
private
SourceFileGenerator
(
TextWriter
writer
)
{
output
=
new
TextGenerator
(
writer
);
}
/// <summary>
/// Creates a ClassFileGenerator for the given writer, which will be closed
/// when the instance is disposed. The specified namespace is created, if it's non-null.
/// </summary>
internal
static
SourceFileGenerator
ForWriter
(
TextWriter
writer
)
{
return
new
SourceFileGenerator
(
writer
);
}
}
}
csharp/ProtoGen/SourceGeneratorBase.cs
0 → 100644
View file @
e60ce8bf
using
System.Collections.Generic
;
using
Google.ProtocolBuffers.DescriptorProtos
;
using
Google.ProtocolBuffers.Descriptors
;
namespace
Google.ProtocolBuffers.ProtoGen
{
internal
abstract
class
SourceGeneratorBase
<
T
>
where
T
:
IDescriptor
{
private
readonly
T
descriptor
;
protected
SourceGeneratorBase
(
T
descriptor
)
{
this
.
descriptor
=
descriptor
;
}
protected
T
Descriptor
{
get
{
return
descriptor
;
}
}
protected
string
ClassAccessLevel
{
get
{
// Default to public
return
!
descriptor
.
File
.
Options
.
HasExtension
(
CSharpOptions
.
CSharpPublicClasses
)
||
descriptor
.
File
.
Options
.
GetExtension
(
CSharpOptions
.
CSharpPublicClasses
)
?
"public"
:
"internal"
;
}
}
public
bool
MultipleFiles
{
get
{
return
descriptor
.
File
.
Options
.
GetExtension
(
CSharpOptions
.
CSharpMultipleFiles
);
}
}
protected
static
void
WriteChildren
<
TChild
>(
TextGenerator
writer
,
string
region
,
IEnumerable
<
TChild
>
children
)
where
TChild
:
IDescriptor
{
// Copy the set of children; makes access easier
List
<
TChild
>
copy
=
new
List
<
TChild
>(
children
);
if
(
copy
.
Count
==
0
)
{
return
;
}
if
(
region
!=
null
)
{
writer
.
WriteLine
(
"#region {0}"
,
region
);
}
foreach
(
TChild
child
in
children
)
{
SourceGenerators
.
CreateGenerator
(
child
).
Generate
(
writer
);
}
if
(
region
!=
null
)
{
writer
.
WriteLine
(
"#endregion"
);
writer
.
WriteLine
();
}
}
}
}
csharp/ProtoGen/SourceGenerators.cs
0 → 100644
View file @
e60ce8bf
using
System
;
using
System.Collections.Generic
;
using
Google.ProtocolBuffers.Descriptors
;
namespace
Google.ProtocolBuffers.ProtoGen
{
internal
static
class
SourceGenerators
{
private
static
readonly
Dictionary
<
Type
,
Func
<
IDescriptor
,
ISourceGenerator
>>
GeneratorFactories
=
new
Dictionary
<
Type
,
Func
<
IDescriptor
,
ISourceGenerator
>>
{
{
typeof
(
FileDescriptor
),
descriptor
=>
new
UmbrellaClassGenerator
((
FileDescriptor
)
descriptor
)
},
{
typeof
(
EnumDescriptor
),
descriptor
=>
new
EnumGenerator
((
EnumDescriptor
)
descriptor
)
},
{
typeof
(
ServiceDescriptor
),
descriptor
=>
new
ServiceGenerator
((
ServiceDescriptor
)
descriptor
)
},
{
typeof
(
MessageDescriptor
),
descriptor
=>
new
MessageGenerator
((
MessageDescriptor
)
descriptor
)
},
// For other fields, we have IFieldSourceGenerators.
{
typeof
(
FieldDescriptor
),
descriptor
=>
new
ExtensionGenerator
((
FieldDescriptor
)
descriptor
)
}
};
public
static
IFieldSourceGenerator
CreateFieldGenerator
(
FieldDescriptor
field
)
{
switch
(
field
.
MappedType
)
{
case
MappedType
.
Message
:
return
field
.
IsRepeated
?
(
IFieldSourceGenerator
)
new
RepeatedMessageFieldGenerator
(
field
)
:
new
MessageFieldGenerator
(
field
);
case
MappedType
.
Enum
:
return
field
.
IsRepeated
?
(
IFieldSourceGenerator
)
new
RepeatedEnumFieldGenerator
(
field
)
:
new
EnumFieldGenerator
(
field
);
default
:
return
field
.
IsRepeated
?
(
IFieldSourceGenerator
)
new
RepeatedPrimitiveFieldGenerator
(
field
)
:
new
PrimitiveFieldGenerator
(
field
);
}
}
public
static
ISourceGenerator
CreateGenerator
<
T
>(
T
descriptor
)
where
T
:
IDescriptor
{
Func
<
IDescriptor
,
ISourceGenerator
>
factory
;
if
(!
GeneratorFactories
.
TryGetValue
(
typeof
(
T
),
out
factory
))
{
throw
new
ArgumentException
(
"No generator registered for "
+
typeof
(
T
).
Name
);
}
return
factory
(
descriptor
);
}
}
}
csharp/ProtoGen/UmbrellaClassGenerator.cs
0 → 100644
View file @
e60ce8bf
using
System
;
using
Google.ProtocolBuffers.DescriptorProtos
;
using
Google.ProtocolBuffers.Descriptors
;
namespace
Google.ProtocolBuffers.ProtoGen
{
/// <summary>
/// Generator for the class describing the .proto file in general,
/// containing things like the message descriptor.
/// </summary>
internal
sealed
class
UmbrellaClassGenerator
:
SourceGeneratorBase
<
FileDescriptor
>,
ISourceGenerator
{
internal
UmbrellaClassGenerator
(
FileDescriptor
descriptor
)
:
base
(
descriptor
)
{
}
public
void
Generate
(
TextGenerator
writer
)
{
WriteIntroduction
(
writer
);
WriteDescriptor
(
writer
);
WriteChildren
(
writer
,
"Extensions"
,
Descriptor
.
Extensions
);
writer
.
WriteLine
(
"#region Static variables"
);
foreach
(
MessageDescriptor
message
in
Descriptor
.
MessageTypes
)
{
new
MessageGenerator
(
message
).
GenerateStaticVariables
(
writer
);
}
writer
.
WriteLine
(
"#endregion"
);
// The class declaration either gets closed before or after the children are written.
if
(!
DescriptorUtil
.
NestClasses
(
Descriptor
))
{
writer
.
Outdent
();
writer
.
WriteLine
(
"}"
);
}
WriteChildren
(
writer
,
"Enums"
,
Descriptor
.
EnumTypes
);
WriteChildren
(
writer
,
"Messages"
,
Descriptor
.
MessageTypes
);
WriteChildren
(
writer
,
"Services"
,
Descriptor
.
Services
);
if
(
DescriptorUtil
.
NestClasses
(
Descriptor
))
{
writer
.
Outdent
();
writer
.
WriteLine
(
"}"
);
}
if
(
DescriptorUtil
.
GetNamespace
(
Descriptor
)
!=
""
)
{
writer
.
Outdent
();
writer
.
WriteLine
(
"}"
);
}
}
private
void
WriteIntroduction
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"// Generated by the protocol buffer compiler. DO NOT EDIT!"
);
writer
.
WriteLine
();
Helpers
.
WriteNamespaces
(
writer
);
if
(
DescriptorUtil
.
GetNamespace
(
Descriptor
)
!=
""
)
{
writer
.
WriteLine
(
"namespace {0} {{"
,
DescriptorUtil
.
GetNamespace
(
Descriptor
));
writer
.
Indent
();
writer
.
WriteLine
();
}
writer
.
WriteLine
(
"{0} static partial class {1} {{"
,
ClassAccessLevel
,
DescriptorUtil
.
GetUmbrellaClassName
(
Descriptor
));
writer
.
WriteLine
();
writer
.
Indent
();
}
private
void
WriteDescriptor
(
TextGenerator
writer
)
{
writer
.
WriteLine
(
"#region Descriptor"
);
writer
.
WriteLine
(
"public static pbd::FileDescriptor Descriptor {"
);
writer
.
WriteLine
(
" get { return descriptor; }"
);
writer
.
WriteLine
(
"}"
);
writer
.
WriteLine
(
"private static readonly pbd::FileDescriptor descriptor = pbd::FileDescriptor.InternalBuildGeneratedFileFrom("
);
writer
.
WriteLine
(
" global::System.Convert.FromBase64String("
);
writer
.
Indent
();
writer
.
Indent
();
// TODO(jonskeet): Consider a C#-escaping format here instead of just Base64.
byte
[]
bytes
=
Descriptor
.
Proto
.
ToByteArray
();
string
base64
=
Convert
.
ToBase64String
(
bytes
);
while
(
base64
.
Length
>
60
)
{
writer
.
WriteLine
(
"\"{0}\" + "
,
base64
.
Substring
(
0
,
60
));
base64
=
base64
.
Substring
(
60
);
}
writer
.
WriteLine
(
"\"{0}\"),"
,
base64
);
writer
.
WriteLine
(
"new pbd::FileDescriptor[] {"
);
foreach
(
FileDescriptor
dependency
in
Descriptor
.
Dependencies
)
{
// TODO(jonskeet): The normal code won't work for the bootstrapping descriptor, because we don't get unknown fields :(
if
(
dependency
.
Package
==
"google.protobuf"
&&
dependency
.
Name
.
EndsWith
(
"descriptor.proto"
))
{
writer
.
WriteLine
(
" global::"
+
typeof
(
DescriptorProtoFile
).
FullName
+
".Descriptor, "
);
continue
;
}
writer
.
WriteLine
(
" {0}.Descriptor, "
,
DescriptorUtil
.
GetFullUmbrellaClassName
(
dependency
));
}
writer
.
WriteLine
(
"});"
);
writer
.
Outdent
();
writer
.
Outdent
();
writer
.
WriteLine
(
"#endregion"
);
writer
.
WriteLine
();
}
}
}
csharp/ProtocolBuffers.Test/TestProtos/UnitTestImportProtoFile.cs
View file @
e60ce8bf
...
...
@@ -12,28 +12,21 @@ namespace Google.ProtocolBuffers.TestProtos {
public
static
pbd
::
FileDescriptor
Descriptor
{
get
{
return
descriptor
;
}
}
private
static
readonly
pbd
::
FileDescriptor
descriptor
=
pbd
::
FileDescriptor
.
InternalBuildGeneratedFileFrom
(
new
byte
[]
{
0x0a
,
0x25
,
0x67
,
0x6f
,
0x6f
,
0x67
,
0x6c
,
0x65
,
0x2f
,
0x70
,
0x72
,
0x6f
,
0x74
,
0x6f
,
0x62
,
0x75
,
0x66
,
0x2f
,
0x75
,
0x6e
,
0x69
,
0x74
,
0x74
,
0x65
,
0x73
,
0x74
,
0x5f
,
0x69
,
0x6d
,
0x70
,
0x6f
,
0x72
,
0x74
,
0x2e
,
0x70
,
0x72
,
0x6f
,
0x74
,
0x6f
,
0x12
,
0x18
,
0x70
,
0x72
,
0x6f
,
0x74
,
0x6f
,
0x62
,
0x75
,
0x66
,
0x5f
,
0x75
,
0x6e
,
0x69
,
0x74
,
0x74
,
0x65
,
0x73
,
0x74
,
0x5f
,
0x69
,
0x6d
,
0x70
,
0x6f
,
0x72
,
0x74
,
0x22
,
0x1a
,
0x0a
,
0x0d
,
0x49
,
0x6d
,
0x70
,
0x6f
,
0x72
,
0x74
,
0x4d
,
0x65
,
0x73
,
0x73
,
0x61
,
0x67
,
0x65
,
0x12
,
0x09
,
0x0a
,
0x01
,
0x64
,
0x18
,
0x01
,
0x20
,
0x01
,
0x28
,
0x05
,
0x2a
,
0x3c
,
0x0a
,
0x0a
,
0x49
,
0x6d
,
0x70
,
0x6f
,
0x72
,
0x74
,
0x45
,
0x6e
,
0x75
,
0x6d
,
0x12
,
0x0e
,
0x0a
,
0x0a
,
0x49
,
0x4d
,
0x50
,
0x4f
,
0x52
,
0x54
,
0x5f
,
0x46
,
0x4f
,
0x4f
,
0x10
,
0x07
,
0x12
,
0x0e
,
0x0a
,
0x0a
,
0x49
,
0x4d
,
0x50
,
0x4f
,
0x52
,
0x54
,
0x5f
,
0x42
,
0x41
,
0x52
,
0x10
,
0x08
,
0x12
,
0x0e
,
0x0a
,
0x0a
,
0x49
,
0x4d
,
0x50
,
0x4f
,
0x52
,
0x54
,
0x5f
,
0x42
,
0x41
,
0x5a
,
0x10
,
0x09
,
0x42
,
0x5a
,
0x0a
,
0x18
,
0x63
,
0x6f
,
0x6d
,
0x2e
,
0x67
,
0x6f
,
0x6f
,
0x67
,
0x6c
,
0x65
,
0x2e
,
0x70
,
0x72
,
0x6f
,
0x74
,
0x6f
,
0x62
,
0x75
,
0x66
,
0x2e
,
0x74
,
0x65
,
0x73
,
0x74
,
0x48
,
0x01
,
0xc2
,
0x3e
,
0x21
,
0x47
,
0x6f
,
0x6f
,
0x67
,
0x6c
,
0x65
,
0x2e
,
0x50
,
0x72
,
0x6f
,
0x74
,
0x6f
,
0x63
,
0x6f
,
0x6c
,
0x42
,
0x75
,
0x66
,
0x66
,
0x65
,
0x72
,
0x73
,
0x2e
,
0x54
,
0x65
,
0x73
,
0x74
,
0x50
,
0x72
,
0x6f
,
0x74
,
0x6f
,
0x73
,
0xca
,
0x3e
,
0x17
,
0x55
,
0x6e
,
0x69
,
0x74
,
0x54
,
0x65
,
0x73
,
0x74
,
0x49
,
0x6d
,
0x70
,
0x6f
,
0x72
,
0x74
,
0x50
,
0x72
,
0x6f
,
0x74
,
0x6f
,
0x46
,
0x69
,
0x6c
,
0x65
,
},
new
pbd
::
FileDescriptor
[]
{
private
static
readonly
pbd
::
FileDescriptor
descriptor
=
pbd
::
FileDescriptor
.
InternalBuildGeneratedFileFrom
(
global
::
System
.
Convert
.
FromBase64String
(
"ChV1bml0dGVzdF9pbXBvcnQucHJvdG8SGHByb3RvYnVmX3VuaXR0ZXN0X2lt"
+
"cG9ydBokZ29vZ2xlL3Byb3RvYnVmL2NzaGFycF9vcHRpb25zLnByb3RvGiBn"
+
"b29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90byIaCg1JbXBvcnRNZXNz"
+
"YWdlEgkKAWQYASABKAUqPAoKSW1wb3J0RW51bRIOCgpJTVBPUlRfRk9PEAcS"
+
"DgoKSU1QT1JUX0JBUhAIEg4KCklNUE9SVF9CQVoQCUJcChhjb20uZ29vZ2xl"
+
"LnByb3RvYnVmLnRlc3RIAYLiCSFHb29nbGUuUHJvdG9jb2xCdWZmZXJzLlRl"
+
"c3RQcm90b3OK4gkXVW5pdFRlc3RJbXBvcnRQcm90b0ZpbGU="
),
new
pbd
::
FileDescriptor
[]
{
global
::
Google
.
ProtocolBuffers
.
DescriptorProtos
.
CSharpOptions
.
Descriptor
,
global
::
Google
.
ProtocolBuffers
.
DescriptorProtos
.
DescriptorProtoFile
.
Descriptor
,
});
#
endregion
#
region
Extensions
#
endregion
#
region
Static
variables
internal
static
readonly
pbd
::
MessageDescriptor
internal__static_protobuf_unittest_import_ImportMessage__Descriptor
=
Descriptor
.
MessageTypes
[
0
];
...
...
@@ -41,9 +34,7 @@ namespace Google.ProtocolBuffers.TestProtos {
=
new
pb
::
FieldAccess
.
FieldAccessorTable
<
global
::
Google
.
ProtocolBuffers
.
TestProtos
.
ImportMessage
,
global
::
Google
.
ProtocolBuffers
.
TestProtos
.
ImportMessage
.
Builder
>(
internal__static_protobuf_unittest_import_ImportMessage__Descriptor
,
new
string
[]
{
"D"
,
});
#
endregion
}
#
region
Enums
public
enum
ImportEnum
{
IMPORT_FOO
=
7
,
...
...
@@ -76,7 +67,6 @@ namespace Google.ProtocolBuffers.TestProtos {
get
{
return
global
::
Google
.
ProtocolBuffers
.
TestProtos
.
UnitTestImportProtoFile
.
internal__static_protobuf_unittest_import_ImportMessage__FieldAccessorTable
;
}
}
// optional int32 d = 1;
private
bool
hasD
;
private
int
d_
=
0
;
public
bool
HasD
{
...
...
@@ -115,62 +105,50 @@ namespace Google.ProtocolBuffers.TestProtos {
}
}
public
static
global
::
Google
.
ProtocolBuffers
.
TestProtos
.
ImportMessage
ParseFrom
(
pb
::
ByteString
data
)
{
public
static
ImportMessage
ParseFrom
(
pb
::
ByteString
data
)
{
return
((
Builder
)
CreateBuilder
().
MergeFrom
(
data
)).
BuildParsed
();
}
public
static
global
::
Google
.
ProtocolBuffers
.
TestProtos
.
ImportMessage
ParseFrom
(
pb
::
ByteString
data
,
pb
::
ExtensionRegistry
extensionRegistry
)
{
return
((
Builder
)
CreateBuilder
().
MergeFrom
(
data
,
extensionRegistry
))
.
BuildParsed
();
public
static
ImportMessage
ParseFrom
(
pb
::
ByteString
data
,
pb
::
ExtensionRegistry
extensionRegistry
)
{
return
((
Builder
)
CreateBuilder
().
MergeFrom
(
data
,
extensionRegistry
)).
BuildParsed
();
}
public
static
global
::
Google
.
ProtocolBuffers
.
TestProtos
.
ImportMessage
ParseFrom
(
byte
[]
data
)
{
public
static
ImportMessage
ParseFrom
(
byte
[]
data
)
{
return
((
Builder
)
CreateBuilder
().
MergeFrom
(
data
)).
BuildParsed
();
}
public
static
global
::
Google
.
ProtocolBuffers
.
TestProtos
.
ImportMessage
ParseFrom
(
byte
[]
data
,
pb
::
ExtensionRegistry
extensionRegistry
)
{
return
((
Builder
)
CreateBuilder
().
MergeFrom
(
data
,
extensionRegistry
))
.
BuildParsed
();
public
static
ImportMessage
ParseFrom
(
byte
[]
data
,
pb
::
ExtensionRegistry
extensionRegistry
)
{
return
((
Builder
)
CreateBuilder
().
MergeFrom
(
data
,
extensionRegistry
)).
BuildParsed
();
}
public
static
global
::
Google
.
ProtocolBuffers
.
TestProtos
.
ImportMessage
ParseFrom
(
global
::
System
.
IO
.
Stream
input
)
{
public
static
ImportMessage
ParseFrom
(
global
::
System
.
IO
.
Stream
input
)
{
return
((
Builder
)
CreateBuilder
().
MergeFrom
(
input
)).
BuildParsed
();
}
public
static
global
::
Google
.
ProtocolBuffers
.
TestProtos
.
ImportMessage
ParseFrom
(
global
::
System
.
IO
.
Stream
input
,
pb
::
ExtensionRegistry
extensionRegistry
)
{
return
((
Builder
)
CreateBuilder
().
MergeFrom
(
input
,
extensionRegistry
))
.
BuildParsed
();
public
static
ImportMessage
ParseFrom
(
global
::
System
.
IO
.
Stream
input
,
pb
::
ExtensionRegistry
extensionRegistry
)
{
return
((
Builder
)
CreateBuilder
().
MergeFrom
(
input
,
extensionRegistry
)).
BuildParsed
();
}
public
static
global
::
Google
.
ProtocolBuffers
.
TestProtos
.
ImportMessage
ParseFrom
(
pb
::
CodedInputStream
input
)
{
public
static
ImportMessage
ParseFrom
(
pb
::
CodedInputStream
input
)
{
return
((
Builder
)
CreateBuilder
().
MergeFrom
(
input
)).
BuildParsed
();
}
public
static
global
::
Google
.
ProtocolBuffers
.
TestProtos
.
ImportMessage
ParseFrom
(
pb
::
CodedInputStream
input
,
pb
::
ExtensionRegistry
extensionRegistry
)
{
return
((
Builder
)
CreateBuilder
().
MergeFrom
(
input
,
extensionRegistry
))
.
BuildParsed
();
public
static
ImportMessage
ParseFrom
(
pb
::
CodedInputStream
input
,
pb
::
ExtensionRegistry
extensionRegistry
)
{
return
((
Builder
)
CreateBuilder
().
MergeFrom
(
input
,
extensionRegistry
)).
BuildParsed
();
}
public
static
Builder
CreateBuilder
()
{
return
new
Builder
();
}
public
override
Builder
CreateBuilderForType
()
{
return
new
Builder
();
}
public
static
Builder
CreateBuilder
(
global
::
Google
.
ProtocolBuffers
.
TestProtos
.
ImportMessage
prototype
)
{
public
static
Builder
CreateBuilder
(
ImportMessage
prototype
)
{
return
(
Builder
)
new
Builder
().
MergeFrom
(
prototype
);
}
public
sealed
partial
class
Builder
:
pb
::
GeneratedBuilder
<
global
::
Google
.
ProtocolBuffers
.
TestProtos
.
ImportMessage
,
Builder
>
{
public
sealed
partial
class
Builder
:
pb
::
GeneratedBuilder
<
ImportMessage
,
Builder
>
{
protected
override
Builder
ThisBuilder
{
get
{
return
this
;
}
}
// Construct using global::Google.ProtocolBuffers.TestProtos.ImportMessage.CreateBuilder()
public
Builder
()
{}
global
::
Google
.
ProtocolBuffers
.
TestProtos
.
ImportMessage
result
=
new
global
::
Google
.
ProtocolBuffers
.
TestProtos
.
ImportMessage
();
ImportMessage
result
=
new
ImportMessage
();
protected
override
global
::
Google
.
ProtocolBuffers
.
TestProtos
.
ImportMessage
MessageBeingBuilt
{
protected
override
ImportMessage
MessageBeingBuilt
{
get
{
return
result
;
}
}
public
override
Builder
Clear
()
{
result
=
new
global
::
Google
.
ProtocolBuffers
.
TestProtos
.
ImportMessage
();
result
=
new
ImportMessage
();
return
this
;
}
...
...
@@ -179,30 +157,30 @@ namespace Google.ProtocolBuffers.TestProtos {
}
public
override
pbd
::
MessageDescriptor
DescriptorForType
{
get
{
return
global
::
Google
.
ProtocolBuffers
.
TestProtos
.
ImportMessage
.
Descriptor
;
}
get
{
return
ImportMessage
.
Descriptor
;
}
}
public
override
global
::
Google
.
ProtocolBuffers
.
TestProtos
.
ImportMessage
DefaultInstanceForType
{
get
{
return
global
::
Google
.
ProtocolBuffers
.
TestProtos
.
ImportMessage
.
DefaultInstance
;
}
public
override
ImportMessage
DefaultInstanceForType
{
get
{
return
ImportMessage
.
DefaultInstance
;
}
}
public
override
global
::
Google
.
ProtocolBuffers
.
TestProtos
.
ImportMessage
BuildPartial
()
{
global
::
Google
.
ProtocolBuffers
.
TestProtos
.
ImportMessage
returnMe
=
result
;
public
override
ImportMessage
BuildPartial
()
{
ImportMessage
returnMe
=
result
;
result
=
null
;
return
returnMe
;
}
public
override
Builder
MergeFrom
(
pb
::
IMessage
other
)
{
if
(
other
is
global
::
Google
.
ProtocolBuffers
.
TestProtos
.
ImportMessage
)
{
return
MergeFrom
((
global
::
Google
.
ProtocolBuffers
.
TestProtos
.
ImportMessage
)
other
);
if
(
other
is
ImportMessage
)
{
return
MergeFrom
((
ImportMessage
)
other
);
}
else
{
base
.
MergeFrom
(
other
);
return
this
;
}
}
public
override
Builder
MergeFrom
(
global
::
Google
.
ProtocolBuffers
.
TestProtos
.
ImportMessage
other
)
{
if
(
other
==
global
::
Google
.
ProtocolBuffers
.
TestProtos
.
ImportMessage
.
DefaultInstance
)
return
this
;
public
override
Builder
MergeFrom
(
ImportMessage
other
)
{
if
(
other
==
ImportMessage
.
DefaultInstance
)
return
this
;
if
(
other
.
HasD
)
{
D
=
other
.
D
;
}
...
...
@@ -215,17 +193,16 @@ namespace Google.ProtocolBuffers.TestProtos {
}
public
override
Builder
MergeFrom
(
pb
::
CodedInputStream
input
,
pb
::
ExtensionRegistry
extensionRegistry
)
{
pb
::
UnknownFieldSet
.
Builder
unknownFields
=
pb
::
UnknownFieldSet
.
CreateBuilder
(
this
.
UnknownFields
);
pb
::
UnknownFieldSet
.
Builder
unknownFields
=
pb
::
UnknownFieldSet
.
CreateBuilder
(
this
.
UnknownFields
);
while
(
true
)
{
uint
tag
=
input
.
ReadTag
();
switch
(
tag
)
{
case
0
:
case
0
:
{
this
.
UnknownFields
=
unknownFields
.
Build
();
return
this
;
}
default
:
{
if
(!
ParseUnknownField
(
input
,
unknownFields
,
extensionRegistry
,
tag
))
{
if
(!
ParseUnknownField
(
input
,
unknownFields
,
extensionRegistry
,
tag
))
{
this
.
UnknownFields
=
unknownFields
.
Build
();
return
this
;
}
...
...
@@ -240,7 +217,6 @@ namespace Google.ProtocolBuffers.TestProtos {
}
// optional int32 d = 1;
public
bool
HasD
{
get
{
return
result
.
HasD
;
}
}
...
...
@@ -263,6 +239,4 @@ namespace Google.ProtocolBuffers.TestProtos {
#
endregion
#
region
Services
#
endregion
}
csharp/ProtocolBuffers/DescriptorProtos/CSharpOptions.cs
0 → 100644
View file @
e60ce8bf
// Generated by the protocol buffer compiler. DO NOT EDIT!
using
pb
=
global
::
Google
.
ProtocolBuffers
;
using
pbc
=
global
::
Google
.
ProtocolBuffers
.
Collections
;
using
pbd
=
global
::
Google
.
ProtocolBuffers
.
Descriptors
;
using
scg
=
global
::
System
.
Collections
.
Generic
;
namespace
Google.ProtocolBuffers.DescriptorProtos
{
public
static
partial
class
CSharpOptions
{
#
region
Descriptor
public
static
pbd
::
FileDescriptor
Descriptor
{
get
{
return
descriptor
;
}
}
private
static
readonly
pbd
::
FileDescriptor
descriptor
=
pbd
::
FileDescriptor
.
InternalBuildGeneratedFileFrom
(
global
::
System
.
Convert
.
FromBase64String
(
"CiRnb29nbGUvcHJvdG9idWYvY3NoYXJwX29wdGlvbnMucHJvdG8SD2dvb2ds"
+
"ZS5wcm90b2J1ZhogZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG86"
+
"NwoPQ1NoYXJwTmFtZXNwYWNlEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRp"
+
"b25zGKCcASABKAk6PwoXQ1NoYXJwVW1icmVsbGFDbGFzc25hbWUSHC5nb29n"
+
"bGUucHJvdG9idWYuRmlsZU9wdGlvbnMYoZwBIAEoCTo7ChNDU2hhcnBNdWx0"
+
"aXBsZUZpbGVzEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGKKcASAB"
+
"KAg6OQoRQ1NoYXJwTmVzdENsYXNzZXMSHC5nb29nbGUucHJvdG9idWYuRmls"
+
"ZU9wdGlvbnMYo5wBIAEoCDo7ChNDU2hhcnBQdWJsaWNDbGFzc2VzEhwuZ29v"
+
"Z2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGKScASABKAhCPILiCSdHb29nbGUu"
+
"UHJvdG9jb2xCdWZmZXJzLkRlc2NyaXB0b3JQcm90b3OK4gkNQ1NoYXJwT3B0"
+
"aW9ucw=="
),
new
pbd
::
FileDescriptor
[]
{
global
::
Google
.
ProtocolBuffers
.
DescriptorProtos
.
DescriptorProtoFile
.
Descriptor
,
});
#
endregion
#
region
Extensions
public
static
readonly
pb
::
GeneratedExtensionBase
<
string
>
CSharpNamespace
=
pb
::
GeneratedSingleExtension
<
string
>.
CreateInstance
(
Descriptor
.
Extensions
[
0
]);
public
static
readonly
pb
::
GeneratedExtensionBase
<
string
>
CSharpUmbrellaClassname
=
pb
::
GeneratedSingleExtension
<
string
>.
CreateInstance
(
Descriptor
.
Extensions
[
1
]);
public
static
readonly
pb
::
GeneratedExtensionBase
<
bool
>
CSharpMultipleFiles
=
pb
::
GeneratedSingleExtension
<
bool
>.
CreateInstance
(
Descriptor
.
Extensions
[
2
]);
public
static
readonly
pb
::
GeneratedExtensionBase
<
bool
>
CSharpNestClasses
=
pb
::
GeneratedSingleExtension
<
bool
>.
CreateInstance
(
Descriptor
.
Extensions
[
3
]);
public
static
readonly
pb
::
GeneratedExtensionBase
<
bool
>
CSharpPublicClasses
=
pb
::
GeneratedSingleExtension
<
bool
>.
CreateInstance
(
Descriptor
.
Extensions
[
4
]);
#
endregion
#
region
Static
variables
#
endregion
}
}
csharp/ProtocolBuffers/DescriptorProtos/DescriptorProtoFile.cs
View file @
e60ce8bf
This source diff could not be displayed because it is too large. You can
view the blob
instead.
csharp/ProtocolBuffers/DescriptorProtos/PartialClasses.cs
View file @
e60ce8bf
...
...
@@ -18,6 +18,21 @@
// autogenerated classes, so that they implement
// IDescriptorProto
namespace
Google.ProtocolBuffers.DescriptorProtos
{
// TODO(jonskeet): Find a better way of fixing this. It's needed in order to
// cope with unknown fields during initialization.
public
partial
class
DescriptorProtoFile
{
private
static
readonly
bool
initialized
=
false
;
internal
static
bool
Bootstrapping
{
get
{
return
!
initialized
;
}
}
static
DescriptorProtoFile
()
{
initialized
=
true
;
}
}
public
partial
class
DescriptorProto
:
IDescriptorProto
<
MessageOptions
>
{
}
public
partial
class
EnumDescriptorProto
:
IDescriptorProto
<
EnumOptions
>
{
}
public
partial
class
EnumValueDescriptorProto
:
IDescriptorProto
<
EnumValueOptions
>
{
}
...
...
csharp/ProtocolBuffers/Descriptors/FileDescriptor.cs
View file @
e60ce8bf
...
...
@@ -181,7 +181,7 @@ namespace Google.ProtocolBuffers.Descriptors {
/// a valid descriptor. This can occur for a number of reasons, such as a field
/// having an undefined type or because two messages were defined with the same name.</exception>
public
static
FileDescriptor
BuildFrom
(
FileDescriptorProto
proto
,
FileDescriptor
[]
dependencies
)
{
// Building de
csriptors involves two steps:
translating and linking.
// Building de
scriptors involves two steps:
translating and linking.
// In the translation step (implemented by FileDescriptor's
// constructor), we build an object tree mirroring the
// FileDescriptorProto's tree and put all of the descriptors into the
...
...
@@ -204,9 +204,9 @@ namespace Google.ProtocolBuffers.Descriptors {
}
for
(
int
i
=
0
;
i
<
proto
.
DependencyCount
;
i
++)
{
if
(
dependencies
[
i
].
Name
!=
proto
.
DependencyList
[
i
])
{
throw
new
DescriptorValidationException
(
result
,
/*
throw new DescriptorValidationException(result,
"Dependencies passed to FileDescriptor.BuildFrom() don't match " +
"those listed in the FileDescriptorProto."
);
"those listed in the FileDescriptorProto.");
*/
}
}
...
...
csharp/ProtocolBuffers/FieldAccess/RepeatedPrimitiveAccessor.cs
View file @
e60ce8bf
...
...
@@ -48,7 +48,7 @@ namespace Google.ProtocolBuffers.FieldAccess {
PropertyInfo
messageProperty
=
typeof
(
TMessage
).
GetProperty
(
name
+
"List"
);
PropertyInfo
builderProperty
=
typeof
(
TBuilder
).
GetProperty
(
name
+
"List"
);
PropertyInfo
countProperty
=
typeof
(
TMessage
).
GetProperty
(
name
+
"Count"
);
MethodInfo
clearMethod
=
typeof
(
TBuilder
).
GetMethod
(
"Clear"
+
name
);
MethodInfo
clearMethod
=
typeof
(
TBuilder
).
GetMethod
(
"Clear"
+
name
,
Type
.
EmptyTypes
);
getElementMethod
=
typeof
(
TMessage
).
GetMethod
(
"Get"
+
name
,
new
Type
[]
{
typeof
(
int
)
});
clrType
=
getElementMethod
.
ReturnType
;
MethodInfo
addMethod
=
typeof
(
TBuilder
).
GetMethod
(
"Add"
+
name
,
new
Type
[]
{
ClrType
});
...
...
csharp/ProtocolBuffers/FieldAccess/SinglePrimitiveAccessor.cs
View file @
e60ce8bf
...
...
@@ -39,10 +39,13 @@ namespace Google.ProtocolBuffers.FieldAccess {
}
internal
SinglePrimitiveAccessor
(
string
name
)
{
PropertyInfo
messageProperty
=
typeof
(
TMessage
).
GetProperty
(
name
);
PropertyInfo
builderProperty
=
typeof
(
TBuilder
).
GetProperty
(
name
);
string
propertyName
=
name
==
typeof
(
TMessage
).
Name
?
name
+
"_"
:
name
;
PropertyInfo
messageProperty
=
typeof
(
TMessage
).
GetProperty
(
propertyName
);
PropertyInfo
builderProperty
=
typeof
(
TBuilder
).
GetProperty
(
name
);
// FIXME!
if
(
builderProperty
==
null
)
builderProperty
=
typeof
(
TBuilder
).
GetProperty
(
propertyName
);
// FIXME!
PropertyInfo
hasProperty
=
typeof
(
TMessage
).
GetProperty
(
"Has"
+
name
);
MethodInfo
clearMethod
=
typeof
(
TBuilder
).
GetMethod
(
"Clear"
+
name
);
MethodInfo
clearMethod
=
typeof
(
TBuilder
).
GetMethod
(
"Clear"
+
name
,
Type
.
EmptyTypes
);
if
(
messageProperty
==
null
||
builderProperty
==
null
||
hasProperty
==
null
||
clearMethod
==
null
)
{
throw
new
ArgumentException
(
"Not all required properties/methods available"
);
}
...
...
csharp/ProtocolBuffers/FieldSet.cs
View file @
e60ce8bf
...
...
@@ -33,6 +33,7 @@ namespace Google.ProtocolBuffers {
/// be impossible to guarantee if this were a public class, of course.
///
/// All repeated fields are stored as IList[object] even
/// TODO(jonskeet): Finish this comment!
/// </summary>
internal
sealed
class
FieldSet
{
...
...
csharp/ProtocolBuffers/ProtocolBuffers.csproj
View file @
e60ce8bf
...
...
@@ -48,6 +48,7 @@
<Compile
Include=
"Collections\Dictionaries.cs"
/>
<Compile
Include=
"Collections\Lists.cs"
/>
<Compile
Include=
"Collections\ReadOnlyDictionary.cs"
/>
<Compile
Include=
"DescriptorProtos\CSharpOptions.cs"
/>
<Compile
Include=
"DescriptorProtos\DescriptorProtoFile.cs"
/>
<Compile
Include=
"DescriptorProtos\IDescriptorProto.cs"
/>
<Compile
Include=
"DescriptorProtos\PartialClasses.cs"
/>
...
...
csharp/ProtocolBuffers/TextGenerator.cs
View file @
e60ce8bf
...
...
@@ -97,6 +97,10 @@ namespace Google.ProtocolBuffers {
Write
(
text
.
Substring
(
pos
));
}
public
void
Write
(
string
format
,
params
object
[]
args
)
{
Write
(
string
.
Format
(
format
,
args
));
}
private
void
Write
(
string
data
)
{
if
(
data
.
Length
==
0
)
{
return
;
...
...
csharp/ProtocolBuffers/UnknownFieldSet.cs
View file @
e60ce8bf
...
...
@@ -18,6 +18,7 @@ using System.Collections.Generic;
using
System.IO
;
using
Google.ProtocolBuffers.Collections
;
using
Google.ProtocolBuffers.Descriptors
;
using
Google.ProtocolBuffers.DescriptorProtos
;
namespace
Google.ProtocolBuffers
{
/// <summary>
...
...
@@ -454,6 +455,11 @@ namespace Google.ProtocolBuffers {
/// <returns>true unless the tag is an end-group tag</returns>
internal
bool
MergeFieldFrom
(
CodedInputStream
input
,
ExtensionRegistry
extensionRegistry
,
IBuilder
builder
,
uint
tag
)
{
if
(
DescriptorProtoFile
.
Bootstrapping
)
{
return
MergeFieldFrom
(
tag
,
input
);
}
MessageDescriptor
type
=
builder
.
DescriptorForType
;
if
(
type
.
Options
.
MessageSetWireFormat
&&
tag
==
WireFormat
.
MessageSetTag
.
ItemStart
)
{
MergeMessageSetExtensionFromCodedStream
(
input
,
extensionRegistry
,
builder
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment